Kotlin offers a feature called inline functions, which might surprise some developers. While function Inline expansion is a common compiler optimization technique for small functions, Kotlin allows programmers to explicitly mark functions for inlining. This capability also exists in other languages like F#, Scala, and C-C++.
This excellent article elucidates the importance of inlining in Kotlin, especially since the language heavily utilizes functions (including lambdas) in places where other languages might use direct code, such as in scope functions. In essence, inlining mitigates the performance overhead associated with function calls.
The article highlights that Kotlin inlines both the function itself and any lambdas passed to it. To confirm this behavior with anonymous functions, a quick test was performed using the apply scope function (marked as inline). Both a lambda expression and an anonymous function were successfully inlined within the apply function.
| |
However, inlining is not always possible, especially when the lambda is defined separately and then passed as a parameter. In such cases, the compiler often cannot determine the specific function being referenced.
| |
This limitation has been confirmed through testing.
Another concept related to inlining is the use of return. Kotlin supports both regular and qualified returns, the latter being denoted by a label. These labelled returns, also called non-local returns, allow nested functions to return from their outer scope.
It’s crucial to note that unqualified returns are not permitted within lambda expressions unless the lambda is inlined. While this might seem counterintuitive, the reasoning becomes clearer when considering the visual structure of lambda expressions. When defined inline, lambdas resemble language constructs like if or while statements. Consequently, a return within such a lambda could be misinterpreted as returning from the enclosing function. This ambiguity is eliminated if the lambda is inlined. Conversely, if the lambda is not inlined, the return would function as expected within the lambda’s scope.
Restricting unqualified returns within non-inlined lambdas enforces consistency and reduces potential confusion, particularly when the same lambda expression might be used in different contexts, leading to varying behaviors depending on inlining.
This exploration of inlining brings to mind a related concept: inline assembly code, supported by languages like C, C++, and even Rust.

