skip to content

What is the trailing-lambda convention in Kotlin, and how do you write `list.filter { it > 0 }` using it?

level: juniorimportance: must knowfreq 80%

answer

  1. Last param is a function → move lambda out
  2. filter({...}) → filter { ... }
  3. Empty () can be dropped
  4. Only the final argument moves out
  5. Makes higher-order calls read like keywords

basics

~20 s

If the last argument to a function is a lambda, you can write it outside the parentheses. So instead of filter({ it > 0 }) you write filter { it > 0 }, which reads more cleanly.

solid answer

~40 s

Kotlin's trailing-lambda convention lets you move a lambda that is the last parameter of a function out of the call's parentheses and place it in braces afterward. `list.filter({ it > 0 })` becomes `list.filter { it > 0 }`. This is purely syntactic sugar enabled by the fact that the lambda is the final argument. If the function takes other arguments, they stay inside the parentheses and only the trailing lambda moves out: `list.fold(0) { acc, x -> acc + x }`. The rule is what makes higher-order functions like `filter`, `map`, `forEach`, and DSL builders read like language constructs rather than ordinary calls. It is the single most pervasive piece of Kotlin syntax for functional code, so candidates must recognize it instantly.

code

kotlin · 6 lines
kotlin
val nums = listOf(-2, 3, -1, 5)
// full form
val a = nums.filter({ n -> n > 0 })
// trailing lambda + implicit it
val b = nums.filter { it > 0 }
println(b) // [3, 5]

go deeper

for a junior

Recognizes the syntax and can rewrite a call between the parenthesized and trailing forms.

for a middle

Knows it only applies to the last parameter and keeps other arguments inside the parentheses.

for a senior

Explains it is pure syntactic sugar that powers DSLs and reads like control flow; distinguishes it from implicit it.

for a principal

Frames it as an API-design lever: putting the function type last so callers get clean trailing-lambda call sites.

## The convention A **lambda** is an anonymous function written in braces, e.g. `{ it > 0 }`. A **higher-order function** is a function that takes another function as a parameter — `filter` takes a *predicate* (a function returning `Boolean`). The **trailing-lambda convention** says: when the **last** parameter of a function is a function type, you may write the corresponding lambda argument **outside** the parentheses. ```kotlin val positives = list.filter({ it > 0 }) // canonical call val positives = list.filter() { it > 0 } // lambda moved out, () stays val positives = list.filter { it > 0 } // empty () dropped — idiomatic ``` All three are the same call. The first form is rarely written by hand; idiomatic Kotlin uses the third. ## With other arguments Only the **last** argument moves out. Earlier arguments stay inside the parentheses: ```kotlin val sum = list.fold(0) { acc, x -> acc + x } // 0 inside, lambda outside val s = buildString(64) { append("hi") } // capacity inside, lambda outside ``` ## Why it exists It makes higher-order calls and DSLs read like built-in control flow. `repeat(3) { ... }` looks like a loop; `apply { ... }` looks like a block. Without it every such call would carry visually noisy `({ ... })`. ## The `it` shorthand When a lambda has exactly one parameter you can omit the parameter list and use the implicit name `it`. That is a separate feature, but it commonly appears together with trailing lambdas (`filter { it > 0 }`).

  • If a function takes two lambdas, can both go outside the parentheses?
    No. Only the single last lambda can move out. The earlier lambda must stay inside the parentheses as a normal argument.

Like taking the bulkiest item out of a packed box and carrying it separately so the box closes neatly.

saying these in an interview costs you the question

  • Thinks trailing lambdas change runtime behavior rather than being syntax sugar
  • Believes any argument (not just the last) can be moved out
  • Confuses the trailing-lambda rule with the implicit `it` rule
  • Cannot rewrite filter({...}) into the idiomatic form

context