Idiomatic Kotlin: Noinline and Crossinline

Tompee Balauag
Familiar Android
Published in
3 min readJul 24, 2018
Photo by Luke Stackpoole on Unsplash

This article is a part of the Idiomatic Kotlin series. The complete list is at the bottom of the article.

If you have been following this series, you should be very familiar with inline functions and the consequences of using them. Today, we will talk about minimizing those consequences by adding restrictions.

Noinline

The noinline modifier allows you to mark a lambda parameter of an inline function to prevent inlining of that same lambda. Now, why would you need to do that? Let’s look at some cases.

Remember reified type parameters? Using reified type parameters requires you to add the inline modifier. This will force all the lambda parameters of that inline function to be inlined. You can mark those lambda parameters that you don’t want to inline with the noinline modifier. As a recap, this code

will output a decompiled code like this

The lambda function was automatically inlined as expected. Adding noinline modifier to the func argument will result in a decompiled code like this.

No surprises. The compiler just ignores the inline modifier and proceed to compile the lambda as an anonymous function.

You can also use noinline to explicitly specify lambda parameters that should not be inlined in cases where you have multiple lambda parameters.

Crossinline

Crossinline allows you to mark a lambda to forbid it from using non-local returns. If you remember, inline lambdas interprets return as non-local returns and return is not allowed on non-inlined lambdas. Let’s see a simple example and also to refresh our memory.

Running this will not output Main finished. This is because the return inside the lambda is a non-local return and will return from the main function. Marking the lambda parameter as crossinline will not allow you to perform non-local return on the lambda.

When is crossinline applicable? Let’s look at a simple case.

Let’s say we have a higher order function that accepts a message and an instance of function type. We know that the function type arguments in a non-inlined function are not allowed to return. Therefore, calling this function from an inline function will throw a compile time error. This is because an inlined lambda is allowed to perform non-local returns. To resolve this, you can mark the lambda parameter of the inline function as crossinline to prevent the call-site from using return.

Check out the other articles in the idiomatic kotlin series. The sample source code for each article can be found here in Github.

  1. Extension Functions
  2. Sealed Classes
  3. Infix Functions
  4. Class Delegation
  5. Local functions
  6. Object and Singleton
  7. Sequences
  8. Lambdas and SAM constructors
  9. Lambdas with Receiver and DSL
  10. Elvis operator
  11. Property Delegates and Lazy
  12. Higher-order functions and Function Types
  13. Inline functions
  14. Lambdas and Control Flows
  15. Reified Parameters
  16. Noinline and Crossinline
  17. Variance
  18. Annotations and Reflection
  19. Annotation Processor and Code Generation

--

--