Advocating against (some) Kotlin expressions.
Both Kotlin in its core (structures & concepts) and IntelliJ IDEA (static analysis tools within it) have the tendency to heavily suggest using expressions wherever possible.



While it’s a cool, concise concept, it has one fundamental flaw:


By a quick glance JUST at the when
branch, you are not able to determine what’s the purpose of the VALUE:

Is it a
returned
value of the function?Is it assigned to a variable?
Is it assigned to a property?
Is it a part of a bigger expression?
…
When you see this kind of a lonely value , you’re obligated to “look up” and search for the context.
The “old”, expression-less approach keeps it all together at a (small?) cost of some repeatability:

Simple cases
This might not be a big issue with simple, one-line when
branches, because:
- A different solution will make the code significantly more repetitive.
- A different solution might make the code less readable.
- You should still be able to control that.

I’d be quite surprised if you’d chosen B
or C
.
Of course A
is the choice you’d go for.
Having one-line when
-branches that just represent values (not necessarily call another method to get the value — more on that later) makes it very simple, yet still surprisingly controllable.
Complex cases
More complicated examples make this thing look differently.

The context is far away from the bottom when
cases. If you want to understand what you’re reading you need to scroll up, changing your focus in the code.
If you don’t believe me here’s the screenshot of my Android Studio:

Extracting complex logic
Let’s back up a little to where this whole contemplation started.
Twitter.
And especially this response to my post:
At first sight it sounds very reasonable:

Smaller, clear, concise… But try to look at the bigger picture.
What can you tell just by looking at the when
case?

Although it looks better, it’s more error prone than having the logic inside the when
branch:


Because:
- Switching context when analysing code can make it more difficult to stay focused and understand what you’re reading.
- It’s not always that easy to scroll the code:

By default git
gives you 3 lines of context (up and down), which may not be enough to see the context of the when
expression.
Which is the exact case in the example above.
More so, wrapping the complexity in a function makes it impossible to be sure whether you should or should not be looking for the context “around” the when
expression. You can only rely on the function name.
This spreads to things like Pull Requests:

Yes, you can tap the (fairly new) button in the Github to
Expand [the code] up
searching for the context of this change. Using this approach means that you always need to assume there is a context to be searched for (you can’t be certain that there’s not).It makes the code prone to errors in Code Review, because it puts more pressure on the reviewer staying focused and analysing the code more thoroughly.
The downside of NOT using when/if expressions
There’s one huge downside of not using when
/if
expressions though:
Exhaustiveness.
Compiler makes sure that when
/if
expressions are exhaustive. This means that:
- It will fail to compile if you’re not returning a value (or throwing an
Exception
) from every single branch of your expression. - If there’s an
enum
used in awhen
condition, compiler will make sure you’ve handled allenum
values.
Here’s where I stand right now.
when
/if
expressions should only be allowed for:

(no one-line method calling)

I’d rather sacrifice the exhaustiveness of complex cases, than have code that might be confusing and easily misunderstood.
What do YOU think about that? Let me know in the comments. Maybe I’ll change my mind.
If you enjoyed this post, please show your support! Clap, follow, comment, share.
This really means a lot!
