Higher-Order Functions: Lambdas as Parameters and Return Values
ver. 1.0.0
How to write, pass, return, and optimize function types and lambdas in Kotlin, including inline behavior and return semantics.
This unit teaches how to declare and use function types in Kotlin, accept and return lambdas, make function parameters optional (nullable or default), extract behavior into lambda parameters to remove duplication, and use
inlineto eliminate runtime overhead. It also covers using inline lambdas to manage resources (e.g.,use,withLock) and explains return semantics inside lambdas: non-local returns, labeled returns, and anonymous functions.
The unit explains function types as first-class types you can write anywhere: parameters, return types, variables, and nullable types (for example (Int, Int) -> Int or ((Int, Int) -> Int)?). You learn to declare functions that accept function-typed parameters and to invoke those parameters, with practical examples such as implementing a simplified filter so collection operations stop feeling like magic.
You learn two ways to make a function parameter optional: give the function-typed parameter a default lambda value, or make the parameter nullable and call it with safe-call (?.invoke()). The unit shows how a function can return another function — building behavior from runtime state (for example selecting a shipping-cost calculator based on delivery method) — and how you can remove duplication between similar functions by extracting the varying part as a lambda parameter.
The runtime cost model of lambdas is explained: ordinary lambdas are compiled as anonymous class instances (heap allocation plus an indirection on invocation). The inline modifier eliminates that cost by substituting the function body and lambda bodies into call sites, removing allocations and calls so the abstraction vanishes at runtime. That capability is used to implement robust resource-management helpers (acquire-run-release patterns) as library functions rather than special syntax: examples include use for closeables and withLock for locks, implemented with inline lambdas.
Finally, the unit clarifies return behavior inside lambdas. A plain return in an inline lambda performs a non-local return from the enclosing function; to return from the lambda only you use a labeled return, or you can write an anonymous function where a plain return is local to that function. Armed with these skills, a learner can design and use higher-order functions, choose when to inline for performance and semantics, and write concise, safe resource-management and control-flow abstractions. The next step suggested is generics: type parameters, erasure, and reified types.
Materials
Source document
- Kotlin in Action, Second Edition, Sebastian Aigner, Roman Elizarov, Svetlana Isakova, and Dmitry Jemerov, Manning, April 2024 — Link — Page 227-251