In a multi-line Kotlin lambda, how is the value the lambda produces determined? Show how this works with a map call.
answer
- Last expression = lambda result
- No implicit return keyword in lambdas
- Statements (val, assignment) are Unit
- Same rule as if/when/= bodies
- Wrong last line -> List<Unit>
basics
~10 sThe last line in the lambda's body is its result automatically. You don't write a return keyword. Whatever that final line evaluates to is what the lambda hands back.
solid answer
~40 sA Kotlin lambda's result is the value of its last expression. There is no implicit `return` keyword inside a lambda body; the final line is simply evaluated and becomes the lambda's return value. Earlier lines run for their side effects or to compute intermediate `val`s. For example, in `list.map { val doubled = it * 2; doubled + 1 }`, each element maps to `doubled + 1` because that is the last expression. Statements that are not expressions (like a `val` declaration or an assignment) have type `Unit` and cannot be the meaningful last line if you need a real value. This 'last expression is the result' rule is the same one used by `if`, `when`, and block bodies of functions written with `=`.
code
kotlin · 5 linesval totals = listOf(1, 2, 3).map {
val base = it * it // intermediate computation
base + 1 // last expression -> mapped value
}
// totals == [2, 5, 10]go deeper
Knows the last expression is the result and that no return keyword is used.
Explains expression-vs-statement and how map infers List<Unit> from a Unit last line.
Connects it to the unifying last-expression rule across if/when/= bodies and contrasts with non-local return.
Frames it as part of Kotlin's expression-oriented design and discusses readability tradeoffs of long multi-statement lambdas vs extracted named functions.
## The rule A **lambda** is a block of code you pass around as a value, written in `{ ... }`. When a lambda has **multiple statements**, Kotlin does NOT require (or allow) a bare `return` to produce its value. Instead, **the value of the last expression in the lambda body is the lambda's result**. ```kotlin val lengths = listOf("a", "bb", "ccc").map { word -> val trimmed = word.trim() // statement 1: declares a val (type Unit as a statement) val n = trimmed.length // statement 2 n * 10 // LAST expression -> this is what the lambda returns } // lengths == [10, 20, 30] ``` ## Expressions vs statements - An **expression** produces a value (`n * 10`, `if (x) 1 else 2`, a function call). - A **statement** is executed for effect and has type `Unit` (`val x = 5`, `println(...)`, an assignment `a = b`). - If your last line is a statement, the lambda returns `Unit`. That is fine for `forEach` but wrong for `map`, where the compiler infers the element type from the last expression. ## Why no `return` keyword? Inside a lambda, a bare `return` would mean **return from the enclosing function** (a non-local return), not from the lambda. To return a value from the lambda itself you either rely on the last-expression rule, or use a **qualified/labeled return** like `return@map value`. ## Same rule everywhere This is the unifying 'last expression' principle in Kotlin: ```kotlin fun f(x: Int) = run { val a = x + 1 a * a // value of run { } and thus of f } val y = if (cond) { log(); 1 } else { 2 } // block-if: last expression wins ``` ## Common pitfall ```kotlin val r = list.map { println(it) // side effect it.length // must be last to be the mapped value } ``` Reversing those two lines would make `map` produce `List<Unit>`.
- What does map return if the last line of the lambda is println(it)?List<Unit>, because println returns Unit and the last expression determines the element type.
- Can you put a bare `return` on the last line to be explicit?No — a bare return targets the enclosing function (non-local return), not the lambda. Use return@map or just the expression.
Like a recipe where the final dish you plate is what you serve — the prep steps before it don't get served, only the last thing on the plate.
saying these in an interview costs you the question
- Saying you must write `return` inside a lambda
- Thinking a `val` declaration can be the result value
- Believing the first line is the result
- Not knowing map infers element type from the last expression
- Confusing lambda result with a non-local return