Alfonso Ristorato
04/14/2026, 2:16 PMtakeIf a lot, and yes, there are other ways to do the below, but please bear with me π
val printlnFn = println("hey")
printlnFn.takeIf { false }?.let { println("true") } ?: println("false")
The output of this will be hey false , and that is fair, but is there a lazy version of takeIf (no there is not, but any recommendation will be helpful) that will allow to call the fn only if the predicate of takeIf satifies?Alfonso Ristorato
04/14/2026, 2:21 PMval printlnFn = { println("hey") }
printlnFn.takeIf { false }?.invoke() ?: println("false")
could work, but still I wonder if there's better πRob Elliot
04/14/2026, 2:24 PMAlfonso Ristorato
04/14/2026, 2:30 PMif/else, you can do a when and this is fine, but if you use takeIf on the method, the method will be called and then either discarded or not according to the predicate within takeIf, I was just wondering if people have ever had a need for a lazy takeIf
Clearer example:
val perEnvCondition = false
fun veryExpensiveCall() = println("I spend a long time")
veryExpensiveCall().takeIf { perEnvCondition } ?: println("I do nothing")Rob Elliot
04/14/2026, 2:31 PMAlfonso Ristorato
04/14/2026, 2:32 PMRob Elliot
04/14/2026, 2:36 PMRob Elliot
04/14/2026, 2:36 PMhfhbd
04/14/2026, 2:37 PMhfhbd
04/14/2026, 2:37 PMAlfonso Ristorato
04/14/2026, 2:37 PMCLOVIS
04/14/2026, 2:38 PM.takeIf if you want to reduce the scope of acceptable values from the previous call.
For example,
someString.indexOf('c').takeIf { it >= 0 }
is ok because it exists to remove negative integers from the domain space.
In all other situations, I avoid takeIf & similar.
(notice that all examples in the documentation follow this pattern)hfhbd
04/14/2026, 2:46 PMRob Elliot
04/14/2026, 2:47 PMhfhbd
04/14/2026, 2:51 PMRob Elliot
04/14/2026, 2:53 PMif (perEnvCondition) {
veryExpensiveCall()
} else {
println("I do nothing")
}CLOVIS
04/14/2026, 2:55 PMconst val perEnvCondition = true
inline fun debug(block: () -> Unit) {
if (perEnvCondition)
block()
}
is much simpler.
Usage:
fun main() {
debug { veryExpensiveCall() }
// β¦
}
This kind of utilities is idiomatic and is common in logging libraries.Alfonso Ristorato
04/14/2026, 2:56 PMAlfonso Ristorato
04/14/2026, 2:57 PMYoussef Shoaib [MOD]
04/14/2026, 3:16 PMletIf, which is a conditional let
For your case, I'd define an onlyIf like so:
inline fun <T: Any> letIf(condition: Boolean, block: () -> T): T? {
contract {
condition holdsIn block
returnsNotNull() implies condition
returns(null) implies !condition
// I have a gripe with this new contract, because it shouldn't be necessary due to contrapositives...
condition implies returnsNotNull()
}
return if (condition) block() else null
}
// Usage
onlyIf(perEnvCondition) { veryExpensiveCall() } ?: println("I do nothing")Oliver.O
04/14/2026, 3:42 PMval printlnFn = println("hey")
Unlike the name suggests, the type of printlnFn is Unit.Alfonso Ristorato
04/14/2026, 3:43 PMOliver.O
04/14/2026, 3:44 PMval printlnFn = { println("hey") }Alfonso Ristorato
04/14/2026, 3:46 PMOliver.O
04/14/2026, 3:47 PMval printlnResult = println("hey")Alfonso Ristorato
04/14/2026, 3:49 PMfn in the name to make it clear that my method is actually a function rather than a side effect generator, but yeah