Lambdas, function types and fun interfaces

Kotlin language Junior Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Predict the output

What does this print?

fun interface Formatter {
    fun format(x: Int): String
}

fun main() {
    val twice: (Int) -> Int = { it * 2 }
    val f = Formatter { "#$it" }
    println(f.format(twice(21)))
    println(buildString { append("a"); append("b") })
}
Options
Hint 1 of 1

What does twice(21) return?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A #42, then ab

Correct. The lambda doubles 21, the fun interface formats it, and buildString uses a receiver lambda.

Why not the others?
  • B #21, then ab. twice(21) runs first and gives 42.
  • C 42, then ab. The formatter adds the # prefix.
  • D It doesn't compile: interfaces can't be created from lambdas. A fun interface can.

30-second answer

A function type like (String) -> Int describes a function's parameters and result, so functions can be passed around as values. A lambda { s: String -> s.length } is a value of that type. A fun interface is an interface with one abstract method that can be created from a lambda (SAM conversion), useful for Java interop and named callbacks.

Practise saying it · 30 s. No recording, just a timer

Explain function types and lambdas.

Say your answer out loud, then check which of these points you covered:

  • Function types describe signatures
  • Lambdas are values
  • fun interface for SAM conversion
  • Lambdas with receivers power DSLs

Deep dive

The last lambda argument can go outside the parentheses: list.forEach { }.

Lambdas capture variables from their scope; capturing a var boxes it in a reference.

Function references (::render) avoid writing a lambda that just forwards.

Receiver function types like StringBuilder.() -> Unit power builders such as buildString { }.

Common mistakes

  • Capturing an Activity in a lambda stored by a long-lived object.
  • Using a typealias where a fun interface would give a clearer name in stack traces and Java.
  • Writing { x -> f(x) } instead of ::f.

Senior take & follow-ups

Mention receivers; they're how Kotlin DSLs, including Compose and Gradle, work.

Follow-up questions

Think of your answer first, then open the hint.

  1. What does buildString { } use?

    Show hint

    A lambda with receiver of type StringBuilder.() -> Unit.

  2. Why use a fun interface instead of a function type?

    Show hint

    A named type, Java-friendly SAM conversion, and room for default methods.

Similar on iOS: Closures and capture lists Swift closures capture by reference too, but need explicit capture lists to avoid retain cycles.

Suggest a fix if something here is wrong or out of date.