Kotlin with Copilot: Create a one line lambda function
Video: Kotlin with Copilot: Create a one line lambda function by Taught by Celeste AI - AI Coding Coach
Kotlin: One-Line Lambda Function
val double: (Int) -> Int = { it * 2 }. The body is a single expression — noreturn, no braces. The minimal lambda.
A small puzzle: compress a lambda to its smallest readable form. The Kotlin idiom is to drop the parameter name (use it), drop the explicit return, and let the type annotation do the rest.
The Copilot prompt
// One-line lambda function that doubles an integer
val double: (Int) -> Int =
Copilot generates:
val double: (Int) -> Int = { number -> number * 2 }
fun main() {
val result = double(5)
println("Double of 5 is $result") // 10
}
Three increasingly compact forms
// 1. Explicit parameter name
val double: (Int) -> Int = { number -> number * 2 }
// 2. Implicit `it` (single param)
val double: (Int) -> Int = { it * 2 }
// 3. Inferred type, implicit it
val double = { x: Int -> x * 2 }
All three produce the same (Int) -> Int function. Idiomatic Kotlin uses the second or third form.
Why drop the name?
For long-named parameters (firstNameWithMiddleInitial), explicit names help. For one-shot single-arg lambdas where the meaning is obvious, it is cleaner:
listOf(1, 2, 3).map { it * 2 }
listOf("a", "bb", "ccc").map { it.length }
listOf(1, 2, 3, 4).filter { it > 2 }
Three idiomatic uses. None benefit from a named parameter — the function's purpose is obvious from context.
Single-expression vs block bodies
// Single expression — no return, no braces around body
val double: (Int) -> Int = { it * 2 }
// Block body — needs explicit return
val double: (Int) -> Int = {
val result = it * 2
return@double result // explicit; for show
}
For one-line lambdas, no return needed — the last expression is the result.
For named functions:
// Single-expression body
fun double(x: Int): Int = x * 2
// Block body — needs return
fun double(x: Int): Int {
return x * 2
}
Same idea: = for single-expression, braces + return for block. The single-expression form is preferred for one-liner functions.
Using one-line lambdas with stdlib
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 } // [2, 4, 6, 8, 10]
val filtered = numbers.filter { it > 2 } // [3, 4, 5]
val sum = numbers.fold(0) { a, b -> a + b } // 15
These read like English: "double each," "filter where greater than 2," "fold from 0 by summing." That's the design goal.
When not to compress
Compressing too aggressively hurts readability:
// Hard to read
list.filter { it.firstOrNull()?.let { c -> c.isUpperCase() } ?: false }
// Easier
list.filter { word ->
val firstChar = word.firstOrNull()
firstChar != null && firstChar.isUpperCase()
}
The longer version is clearer. Compress when meaning is obvious; expand when it isn't.
Storing many small lambdas
For dispatch tables:
val ops: Map<String, (Int, Int) -> Int> = mapOf(
"+" to { a, b -> a + b },
"-" to { a, b -> a - b },
"*" to { a, b -> a * b },
"/" to { a, b -> a / b },
)
val result = ops["+"]?.invoke(5, 3) // 8
A map of one-line lambdas keyed by operator. Cleaner than a giant when block when adding ops dynamically.
Function references for the simplest cases
When the lambda is just calling an existing function, use a reference:
listOf(-1, 2, -3, 4).map { kotlin.math.abs(it) } // {it -> abs(it)}
listOf(-1, 2, -3, 4).map(::abs) // function reference
::abs is the function reference. Equivalent but clearer when the lambda is "just call this function."
Common mistakes
Multiple statements in a single-expression lambda. { it * 2 + 1 } works; { println(it); it * 2 } works (last expression is the value). But { val x = it; println(x) } returns Unit, not the value of x. Be careful what's last.
Compressing nested lambdas to it. list.map { list.map { it } } — the inner it shadows the outer. Rename one explicitly.
Forgetting types when needed. val f = { x -> x * 2 } doesn't compile — Kotlin can't infer x's type. Use val f = { x: Int -> x * 2 } or val f: (Int) -> Int = { x -> x * 2 }.
Confusing single-expression with no-arg. { println("hi") } is a single-expression lambda with no params (returns Unit). { -> println("hi") } is the explicit no-args form (rare; only needed in some contexts).
Compressing past readability. A 5-character lambda is great; a 50-character one needs to be expanded.
What's next
Episode 30: Lambda to add 2 numbers. A two-arg lambda — the (Int, Int) -> Int version.
Recap
The compact lambda: { it * 2 }. Drop param name when it's a single arg with obvious meaning. No return needed for single-expression bodies. Type the variable (val f: (Int) -> Int) or the parameter ({ x: Int -> ... }) — Kotlin needs one or the other. For "just call this function," prefer ::name over a wrapping lambda. Compress when readable; expand when not.
Next episode: 2-arg add lambda.