Idiomatic Kotlin: Lambdas and Control Flows
This article is a part of the Idiomatic Kotlin series. The complete list is at the bottom of the article.
Now that we have discussed higher order functions and inlining, we are now ready to investigate control flows in lambdas and higher order functions.
Lambda returns
First on our list is the lambda return. How exactly does the return
statement behave inside a lambda? Let’s check an example.
Notice that a compile error is generated when you add a return
to a lambda. This is because in Kotlin, it is not allowed to return from a function inside a lambda.
How to then exit from a lambda you say? Read on.
Return with Labels
To return from a lambda and continue execution from where it was invoked, you need to define a label and return to that. Labels are defined after the function definition appended with @
.
Alternatively, you can omit the label declaration and return using the function name instead. Let’s see the output of this code
Found Spock
Did we find Spock?
End of findStudentTest
This works like a break
statement inside a loop. This is called local return.
Anonymous Function Returns
Let’s use the same example but this time, using anonymous functions instead.
Running this code will output
Found Spock
Did we find Spock?
End of findStudentTest
We can see therefore that a return inside an anonymous function returns from the anonymous function. This is similar to the return with label behavior.
Inline functions
We know that inlining a function copies the bytecode of the function at the call-site. Will this affect return statements? Let’s find out. Consider this example.
This code will not compile because of the same reasons as the first example. It will say that return
is not allowed. Will this change if we inline the function instead?
Inlining will not produce a compile error. Now, how does it behave. Let’s see the output.
Not Spock
Found Spock
We can see that it returns from the enclosing function. This is somewhat expected since the function is inlined to the call-site. This behavior is the same as the return inside a for
loop. This is called non-local return.
We can find a pattern here. return
returns to the nearest fun
declaration. In inlined lambdas, the enclosing function is where the nearest fun
declaration is, that’s why it returns outside of the enclosing function. In anonymous functions, the nearest fun
is at the anonymous function declaration.
Check out the other articles in the idiomatic kotlin series. The sample source code for each article can be found here in Github.
- Extension Functions
- Sealed Classes
- Infix Functions
- Class Delegation
- Local functions
- Object and Singleton
- Sequences
- Lambdas and SAM constructors
- Lambdas with Receiver and DSL
- Elvis operator
- Property Delegates and Lazy
- Higher-order functions and Function Types
- Inline functions
- Lambdas and Control Flows
- Reified Parameters
- Noinline and Crossinline
- Variance
- Annotations and Reflection
- Annotation Processor and Code Generation