https://kotlinlang.org logo
#announcements
Title
# announcements
a

Antanas A.

06/14/2019, 6:49 AM
Hi, It would be nice that extension functions such us
inline fun <T> T.takeUnless
would work lazily and short circuit code execution if condition is true, kind of lazy evaluation of
previous expression
. What's your thoughts? Is it possible at all?
g

gildor

06/14/2019, 6:59 AM
what should be done lazy? I’m not sure how is that possible for such function
T already there and it must be returned immidiately
because predicate requires T it cannot be lazy
but you can write own extension that doesn’t require eager receiver and just have additional lambda that computes lazily
But it will not be takeUnless anymore semantically
p

Pavlo Liapota

06/14/2019, 7:17 AM
I am not sure what do you mean by
kind of lazy evaluation of
previous expression
takeUnless
returns
null
if condition is
true
. But I guess what you want is just
Copy code
if (condition) null else foo()
Soo
foo()
is evaluated only if condition is
false
. And of course you can create extension function with a condition as a receiver, if it makes sense for you.
a

Antanas A.

06/14/2019, 7:27 AM
yeah, after closer inspection I've noticed that
takeUnless
passes a value into predicate function
and I, until today, I've used it as if(condition) null else codeblock() replacement
I've replaced it with extension function as suggested
fun <T> takeUnless(predicate: Boolean, block: () -> T): T? = if (!predicate) block() else null
at first I just thought if it's inline fun then it will be inlined in code, and will wrap (somehow) expression/variable on which it was called
my case is
Copy code
val event = GeneratedEvent(
                    on = true,
                    timestamp = randomize(randomSeed, max(visibleRange.start, interval.start - RandomizationRange), interval.start),
                    totalVehicleMiles = dutyEvent.totalVehicleMiles
                ).takeUnless { interval.start == visibleRange.start }
as this code was written before, and the special condition just emerged after requirements change
so writing "takeUnless" on the end looked as fastest solution 🙂
g

gildor

06/14/2019, 7:34 AM
why not just:
Copy code
val event = if (interval.start != visibleRange.start) {
 GeneratedEvent(…)
} else {
  null
}
takeUnless without receiver looks really strange
a

Antanas A.

06/14/2019, 7:34 AM
actually in production code there is a listOf( ..., ..., ..., ... ).filterNotNull()
yes, I've misused takeUnless, I'd haven't thought that its predicate function receives value as argument and used as just kind of generic "convert to null if {any expression is true}"
will change my behaviour from now 🙂
thanks
d

Dico

06/15/2019, 5:58 AM
I used to declare an extension function like Boolean.ifTrue { } Which works like also but only if it's true... just not a fan of the name
2 Views