To inline, or noinline, that is the question!

One of the reason why Kotlin became as primary language in Android is updates come really fast! Some bug fixes, improvements or new functionalities every time. With every update, kotlin also tries to force developer not to make mistakes! Which is my favorite :)

With the latest release of Kotlin 1.1.4–2 a new compilation error type is introduced, which warns you when you try to have a nullable parameter in an inline function.

For more information about this, you can read through the issue here and you can check here to see how they converted it to error.

Even though some people promote Kotlin as “you won’t have NPE anymore”, “it is handled in compile time”, “compiler supports you, now.” and so on.

NullPointerException is still a developer mistake!

And regardless the Kotlin compiler trying to help you as much as possible, it is still possible to introduce them. Or even convert them into some other exceptions:

  • IllegalStateException - if you have !! but you got null.
  • UninitializedPropertyAccessException - when you have lateinit but you try to access the field before you initialize it.

In Kotlin, most of the time, you should not need to type “null”. If you do, either you are doing something wrong or you should refactor your legacy code in a more kotlin way.

So, what is this new error type about?

Let’s assume you have this inlined extension function to do something. But it has multiple states that can happen and most of the time you ignore the second one.

inline fun SomeClass.fancyExtension(firstAction: () -> Unit, 
optional: ((throwable: Throwable) -> Unit)? = null) {

try {
doSomethingMightThrowException()
firstAction()
} catch (exception: IllegalStateException) {
optional?.invoke(exception)
}
}

Easy, right? You just put null there and ignore it if the parameter is null.

And of course, Kotlin tries to warn you again; “Hey! Something is not right there, you feel it?” and you kept ignoring that, now you cannot. It is a compile time error, saying:

Inline-parameter ‘…’ of `public inline fun …` defined in `…` file must not be nullable. Add `noinline` modifier to the parameter declaration or make its type not nullable.

Perfect! They even tell us how to work around this! But what is the reason?

Well, unfortunately, right now (August 2017) Kotlin doesn’t support optional parameters in inline functions. But good news, warning says “not supported yet”.

When you introduce nullable parameters, basically you use this loophole.

What about no need to type null?

Yes, I mentioned something like that. How to Kotlinize this? Let’s remove nullability there but still have a default value, which we can still ignore.

val stubOptional: (throwable: Throwable) -> Unit = {}

inline fun SomeClass.fancyExtension(firstAction: () -> Unit, 
noinline optional: (throwable: Throwable) -> Unit = stubOptional){

try {
doSomethingMightThrowException()
firstAction()
} catch (exception: IllegalStateException) {
optional.invoke(exception)
}
}

Read more about inline functions here and think about when to use https://kotlinlang.org/docs/reference/inline-functions.html


Nullability should not be necessarily something you introduce, but can be also something you need to maintain from legacy code in Java. Of course, it is possible to use null in Kotlin, but try to find another way so that you really don’t need to. Only then you can actually avoid having NullPointerException.