https://kotlinlang.org logo
Title
m

Mark

03/01/2021, 2:41 PM
Is there a nicer way to write this:
val resultOrNull = firstAttemptOrNull() ?: run {
    if (someConditionMet()) {
        secondAttemptOrNull()
    } else {
        null
    }
}
d

dfriehs

03/01/2021, 3:41 PM
you could remove the
run
block (and consider a
when
block instead of
if
):
val resultOrNull = firstAttemptOrNull() ?: when {
    someConditionMet() -> secondAttemptOrNull()
    else -> null
}
👍 2
j

Joel

03/01/2021, 7:16 PM
firstAttemptOrNull() ?: secondAttemptOrNull()?.takeIf { someConditionMet() }
downside is that it will run
secondAttemptOrNull
even if
someConditionMet
is false and then drop result on the floor. Unsure if there's a helper that runs the conditional first, like an
if
statement that runs a lambda.
firstAttemptOrNull() ?: if (someConditionMet()) secondAttemptOrNull() else null
is also valid
👍 1
m

Mark

03/02/2021, 1:58 AM
How about declaring a simple top-level fun:
inline fun <R> otherwiseIf(condition: Boolean, block: () -> R): R? = if (condition) {
    block()
} else {
    null
}
And then we can do:
val resultOrNull = firstAttemptOrNull()
    ?: otherwiseIf(someConditionMet) {
        secondAttemptOrNull()
    }
j

Joel

03/02/2021, 2:00 AM
You could, but it looks so much like a normal
if
I'd have to question if we're only doing it because we can 🙂
I've done like
someConditionMet().ifTrue { secondAttemptOrNull() }
but have never been happy with how it feels. I wish there were a nullable
if
statement syntax built-in.
firstAttemptOrNull() ?: if? (someConditionMet()) secondAttemptOrNull()
would be sweet, and parallel features such as
as?
m

Mark

03/02/2021, 2:02 AM
Yeah I agree. The big drawback is it opens the question “how does otherwiseIf()/ifTrue() actually work” so make the code more difficult to read in some sense.
j

Joel

03/02/2021, 2:03 AM
I have
orElse
in my codebase because it reads nicely, but I can't think of good syntax for the inverse that is meaningfully different from
if
. i.e.
thisThingIsValid.orElse { doSomething() }
👍 1
m

Mark

03/02/2021, 2:05 AM
ifTrue
would be a much better name for my
otherwiseIf
function of course!