skip to content

In a multi-line Kotlin lambda, how is the value the lambda produces determined? Show how this works with a map call.

level: juniorimportance: must knowfreq 78%

answer

  1. Last expression = lambda result
  2. No implicit return keyword in lambdas
  3. Statements (val, assignment) are Unit
  4. Same rule as if/when/= bodies
  5. Wrong last line -> List<Unit>

basics

~10 s

The 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 s

A 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 lines
kotlin
val totals = listOf(1, 2, 3).map {
    val base = it * it   // intermediate computation
    base + 1             // last expression -> mapped value
}
// totals == [2, 5, 10]

go deeper

for a junior

Knows the last expression is the result and that no return keyword is used.

for a middle

Explains expression-vs-statement and how map infers List<Unit> from a Unit last line.

for a senior

Connects it to the unifying last-expression rule across if/when/= bodies and contrasts with non-local return.

for a principal

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

context