Is there a nicer way to write this: ```val resultO...
# codereview
m
Is there a nicer way to write this:
Copy code
val resultOrNull = firstAttemptOrNull() ?: run {
    if (someConditionMet()) {
        secondAttemptOrNull()
    } else {
        null
    }
}
d
you could remove the
run
block (and consider a
when
block instead of
if
):
Copy code
val resultOrNull = firstAttemptOrNull() ?: when {
    someConditionMet() -> secondAttemptOrNull()
    else -> null
}
👍 2
j
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
How about declaring a simple top-level fun:
Copy code
inline fun <R> otherwiseIf(condition: Boolean, block: () -> R): R? = if (condition) {
    block()
} else {
    null
}
And then we can do:
Copy code
val resultOrNull = firstAttemptOrNull()
    ?: otherwiseIf(someConditionMet) {
        secondAttemptOrNull()
    }
j
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
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
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
ifTrue
would be a much better name for my
otherwiseIf
function of course!