I'm torn … do you extract the `return` even if som...
# codereview
h
I'm torn … do you extract the
return
even if some branches don't return anything? I think I might like the version with multiple return statements better in this case…
Copy code
return if (someExpr) {
  doSomeStuff()
  someThing
} else if (otherExpr) {
  doOtherStuff()
  otherThing
} else {
  throw RuntimeException("uh oh")
}
j
I extract those branches into functions with proper names that return a value, and then lift the
return
out of the
if
when I have one-liners in every branch. I would also likely make it a
when
because I think they look better as expressions than
if
when the whole
if
doesn't fit on a single line (especially if there are more than 2 branches)
Then extract the
when
expression into its own function so there is not even one
return
anymore
In short, your snippet in its context (which we don't have here) will likely look like:
Copy code
return theWhenStuff()
With the following extra declarations:
Copy code
fun theWhenStuff() = when {
    someExpr -> doSomeStuffThatReturnsSomeThing()
    otherExpr -> doSomeOtherStuffThatReturnOtherThing()
    else -> error("uh oh")
}

fun doSomeStuffThatReturnsSomeThing() {
    doSomeStuff()
    return someThing
}

fun doSomeOtherStuffThatReturnOtherThing() {
    doOtherStuff()
    return otherThing
}
even if some branches don't return anything
So your problem is with the
throw
there? That doesn't bother me. Throw returns
Nothing
which makes the whole thing clean IMO
h
I really should make more (smaller) methods 🤦‍♂️ Thank you, that pushed me on the right track!
j
I'm sorry I initially missed the actual point of the question. But I guess it becomes kinda moot once you extract more functions. I imagine you don't really have a problem with calling functions that can either throw or return something (basically all functions are like that), so I'd say having an expression that mixes values and failure doesn't really bother me either, in the same way. The most obvious example of it would be:
Copy code
val x = something ?: throw SomeException("blah")
// or
return something ?: throw SomeException("blah")
Although I have to admit this last part itches a tiny little bit. It would depend on context I guess
j
I like the shift from
if
to
when
there. With the way the two are naturally indented, the
when
statement does a much better job of visually associating all of the branches back to the
return
.