Advocating against (some) Kotlin expressions.

Bartek Lipinski
ProAndroidDev
Published in
5 min readMar 11, 2019

--

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.

Single expression function.
if expression.
when expression (not fully optimized on purpose).

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:

You absolutely need to search for the context.

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:

  1. A different solution will make the code significantly more repetitive.
  2. A different solution might make the code less readable.
  3. 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:

(you have to scroll up to see what this `when` is all about)

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?

(or just “working” on the `rawPizza` argument?)

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

Because:

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

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:

  1. It will fail to compile if you’re not returning a value (or throwing an Exception) from every single branch of your expression.
  2. If there’s an enum used in a when condition, compiler will make sure you’ve handled all enum 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!

Be sure to follow me on Twitter:

--

--

android engineer @whatnot | ex @reddit | ex @getthefabulous | recovering feature creep 💉 | https://github.com/blipinsk