Lesson 10 / 25
Lambdas and Higher-Order Functions
Function types, trailing lambdas and it.
Passing behaviour around
A higher-order function takes a function as a parameter or returns one. Function types are written like (Int, Int) -> Int, and nullable as ((String) -> Unit)?. A lambda is written in braces: { a, b -> a + b }; a single parameter can be referred to as it. If the last parameter is a function, the lambda can go outside the parentheses (trailing lambda syntax). Function references such as ::isValid or String::length pass existing functions. Marking a higher-order function inline removes lambda allocation overhead and allows return from the enclosing function inside the lambda.
Functions as values
Lambdas, a rich collections API and extension functions make Kotlin code declarative and readable.
A retry helper taking a lambda
Trailing lambda syntax.
fun <T> retry(times: Int = 3, block: () -> T): T {
var lastError: Exception? = null
repeat(times) {
try {
return block()
} catch (e: Exception) {
lastError = e
}
}
throw IllegalStateException("failed after $times attempts", lastError)
}
fun isEven(n: Int) = n % 2 == 0
fun main() {
val sum: (Int, Int) -> Int = { a, b -> a + b }
val evens = listOf(1, 2, 3, 4).filter(::isEven) // function reference
val lengths = listOf("a", "bb").map { it.length } // it = single parameter
val value = retry(times = 2) { sum(1, 2) } // trailing lambda
}A recipe with a blank step
A higher-order function is a recipe with one step left open, such as "season to taste"; the lambda you pass fills in that step.
Quick check: What does `it` refer to in `list.map { it * 2 }`?
- The single parameter of the lambda, each element in turn
- The list itself
- The index of the element
- The result of the previous call
Answer
The single parameter of the lambda, each element in turn — it is the implicit name of a single lambda parameter.