Edit Page

# Functional programming

## Function types

Like in Python, functions in Kotlin are first-class values - they can be assigned to variables and passed around as parameters. The type a function is a function type, which is indicated with a parenthesized parameter type list and an arrow to the return type. Consider this function:

``````fun safeDivide(numerator: Int, denominator: Int) =
if (denominator == 0) 0.0 else numerator.toDouble() / denominator
``````

It takes two `Int` parameters and returns a `Double`, so its type is `(Int, Int) -> Double`. We can reference the function itself by prefixing its name with `::`, and we can assign it to a variable (whose type would normally be inferred, but we show the type signature for demonstration):

``````val f: (Int, Int) -> Double = ::safeDivide
``````

When you have a variable or parameter of function type (sometimes called a function reference), you can call it as if it were an ordinary function, and that will cause the referenced function to be called:

``````val quotient = f(3, 0)
``````

It is possible for a class to implement a function type as if it were an interface. It must then supply an operator function called `invoke` with the given signature, and instances of that class may then be assigned to a variable of that function type:

``````class Divider : (Int, Int) -> Double {
override fun invoke(numerator: Int, denominator: Int): Double = ...
}
``````

## Function literals: lambda expressions and anonymous functions

Like in Python, you can write lambda expressions: unnamed function declarations with a very compact syntax, which evaluate to callable function objects. In Kotlin, lambdas can contain multiple statements, which make them useful for more complex tasks than the single-expression lambdas of Python. The last statement must be an expression, whose result will become the return value of the lambda (unless `Unit` is the return type of the variable/parameter that the lambda expression is assigned to, in which case the lambda has no return value). A lambda expression is enclosed in curly braces, and begins by listing its parameter names and possibly their types (unless the types can be inferred from context):

``````val safeDivide = { numerator: Int, denominator: Int ->
if (denominator == 0) 0.0 else numerator.toDouble() / denominator
}
``````

The type of `safeDivide` is `(Int, Int) -> Double`. Note that unlike function type declarations, the parameter list of a lambda expression must not be enclosed in parentheses.

Note that the other uses of curly braces in Kotlin, such as in function and class definitions and after `if`/`else`/`for`/`while` statements, are not lambda expressions (so it is not the case that `if` is a function that conditionally executes a lambda function).

The return type of a lambda expression is inferred from the type of the last expression inside it (or from the function type of the variable/parameter that the lambda expression is assigned to). If a lambda expression is passed as a function parameter (which is the ordinary use) or assigned to a variable with a declared type, Kotlin can infer the parameter types too, and you only need to specify their names:

``````val safeDivide: (Int, Int) -> Double = { numerator, denominator ->
if (denominator == 0) 0.0 else numerator.toDouble() / denominator
}
``````

Or:

``````fun callAndPrint(function: (Int, Int) -> Double) {
println(function(2, 0))
}

callAndPrint({ numerator, denominator ->
if (denominator == 0) 0.0 else numerator.toDouble() / denominator
})
``````

A parameterless lambda does not need the arrow. A one-parameter lambda can choose to omit the parameter name and the arrow, in which case the parameter will be called `it`:

``````val square: (Double) -> Double = { it * it }
``````

If the type of the last parameter to a function is a function type and you want to supply a lambda expression, you can place the lambda expression outside of the parameter parentheses. If the lambda expression is the only parameter, you can omit the parentheses entirely. This is very useful for constructing DSLs.

``````fun callWithPi(function: (Double) -> Double) {
println(function(3.14))
}

callWithPi { it * it }
``````

If you want to be more explicit about the fact that you're creating a function, you can make an anonymous function, which is still an expression rather than a declaration:

``````callWithPi(fun(x: Double): Double { return x * x })
``````

Or:

``````callWithPi(fun(x: Double) = x * x)
``````

Lambda expressions and anonymous functions are collectively called function literals.

## Comprehensions

Kotlin can get quite close to the compactness of Python's `list`/`dict`/`set` comprehensions. Assuming that `people` is a collection of `Person` objects with a `name` property:

``````val shortGreetings = people
.filter { it.name.length < 10 }
.map { "Hello, \${it.name}!" }
``````

corresponds to

``````short_greetings = [
f"Hello, {p.name}"  # In Python 2, this would be: "Hello, %s!" % p.name
for p in people
if len(p.name) < 10
]
``````

In some ways, this is easier to read because the operations are specified in the order they are applied to the values. The result will be an immutable `List<T>`, where `T` is whichever type is produced by the transformations you use (in this case, `String`). If you need a mutable list, call `toMutableList()` at the end. If you want a set, call `toSet()` or `toMutableSet()` at the end. If you want to transform a collection into a map, call `associateBy()`, which takes two lambdas that specify how to extract the key and the value from each element: `people.associateBy({it.ssn}, {it.name})` (you can omit the second lambda if you want the entire element to be the value, and you can call `toMutableMap()` at the end if you want the result to be mutable).

These transformations can also be applied to `Sequence<T>`, which is similar to Python's generators and allows for lazy evaluation. If you have a huge list and you want to process it lazily, you can call `asSequence()` on it.

There's a vast collection of functional programming-style operations available in the `kotlin.collections` package.

The signature of a member function or an extension function begins with a receiver: the type upon which the function can be invoked. For example, the signature of `toString()` is `Any.() -> String` - it can be called on any non-null object (the receiver), it takes no parameters, and it returns a `String`. It is possible to write a lambda function with such a signature - this is called a function literal with receiver, and is extremely useful for building DSLs.

A function literal with receiver is perhaps easiest to think of as an extension function in the form of a lambda expression. The declaration looks like an ordinary lambda expression; what makes it take a receiver is the context - it must be passed to a function that takes a function with receiver as a parameter, or assigned to a variable/property whose type is a function type with receiver. The only way to use a function with receiver is to invoke it on an instance of the receiver class, as if it were a member function or extension function. For example:

``````class Car(val horsepowers: Int)

val boast: Car.() -> String = { "I'm a car with \$horsepowers HP!"}

val car = Car(120)
println(car.boast())
``````

Inside a lambda expression with receiver, you can use `this` to refer to the receiver object (in this case, `car`). As usual, you can omit `this` if there are no naming conflicts, which is why we can simply say `\$horsepowers` instead of `\${this.horsepowers}`. So beware that in Kotlin, `this` can have different meanings depending on the context: if used inside (possibly nested) lambda expressions with receivers, it refers to the receiver object of the innermost enclosing lambda expression with receiver. If you need to "break out" of the function literal and get the "original" `this` (the instance the member function you're inside is executing on), mention the containing class name after `this@` - so if you're inside a function literal with receiver inside a member function of Car, use `this@Car`.

As with other function literals, if the function takes one parameter (other than the receiver object that it is invoked on), the single parameter is implicitly called `it`, unless you declare another name. If it takes more than one parameter, you must declare their names.

Here's a small DSL example for constructing tree structures:

``````class TreeNode(val name: String) {
val children = mutableListOf<TreeNode>()

fun node(name: String, initialize: (TreeNode.() -> Unit)? = null) {
val child = TreeNode(name)
if (initialize != null) {
child.initialize()
}
}
}

fun tree(name: String, initialize: (TreeNode.() -> Unit)? = null): TreeNode {
val root = TreeNode(name)
if (initialize != null) {
root.initialize()
}
return root
}

val t = tree("root") {
node("math") {
node("algebra")
node("trigonometry")
}
node("science") {
node("physics")
}
}
``````

The block after `tree("root")` is the first function literal with receiver, which will be passed to `tree()` as the `initialize` parameter. According to the parameter list of `tree()`, the receiver is of type `TreeNode`, and therefore, `tree()` can call `initialize()` on `root`. `root` then becomes `this` inside the scope of that lambda expression, so when we call `node("math")`, it implicitly says `this.node("math")`, where `this` refers to the same `TreeNode` as `root`. The next block is passed to `TreeNode.node()`, and is invoked on the first child of the `root` node, namely `math`, and inside it, `this` will refer to `math`.

If we had wanted to express the same thing in Python, it would have looked like this, and we would be hamstrung by the fact that lambda functions can only contain one expression, so we need explicit function definitions for everything but the oneliners:

``````class TreeNode:
def __init__(self, name):
self.name = name
self.children = []

def node(self, name, initialize=None):
child = TreeNode(name)
self.children.append(child)
if initialize:
initialize(child)

def tree(name, initialize=None):
root = TreeNode(name)
if initialize:
initialize(root)
return root

def init_root(root):
root.node("math", init_math)
root.node("science",
lambda science: science.node("physics"))

def init_math(math):
math.node("algebra")
math.node("trigonometry")

t = tree("root", init_root)
``````

The official docs also have a very cool example with a DSL for constructing HTML documents.

## Inline functions

There's a little bit of runtime overhead associated with lambda functions: they are really objects, so they must be instantiated, and (like other functions) calling them takes a little bit of time too. If we use the `inline` keyword on a function, we tell the compiler to inline both the function and its lambda parameters (if any) - that is, the compiler will copy the code of the function (and its lambda parameters) into every callsite, thus eliminating the overhead of both the lambda instantiation and the calling of the function and the lambdas. This will happen unconditionally, unlike in C and C++, where `inline` is more of a hint to the compiler. This will cause the size of the compiled code to grow, but it may be worth it for certain small but frequently-called functions.

``````inline fun time(action: () -> Unit): Long {
val start = Instant.now().toEpochMilli()
action()
return Instant.now().toEpochMilli() - start
}
``````

Now, if you do:

``````val t = time { println("Lots of code") }
println(t)
``````

The compiler will generate something like this (except that `start` won't collide with any other identifiers with the same name):

``````val start = Instant.now().toEpochMilli()
println("Lots of code")
val t = Instant.now().toEpochMilli() - start
println(t)
``````

In an inline function definition, you can use `noinline` in front of any function-typed parameter to prevent the lambda that will be passed to it from also being inlined.

## Nice utility functions

### `run()`, `let()`, and `with()`

`?.` is nice if you want to call a function on something that might be null. But what if you want to call a function that takes a non-null parameter, but the value you want to pass for that parameter might be null? Try `run()`, which is an extension function on `Any?` that takes a lambda with receiver as a parameter and invokes it on the value that it's called on, and use `?.` to call `run()` only if the object is non-null:

``````val result = maybeNull?.run { functionThatCanNotHandleNull(this) }
``````

If `maybeNull` is null, the function won't be called, and `result` will be null; otherwise, it will be the return value of `functionThatCanNotHandleNull(this)`, where `this` refers to `maybeNull`. You can chain `run()` calls with `?.` - each one will be called on the previous result if it's not null:

``````val result = maybeNull
?.run { firstFunction(this) }
?.run { secondFunction(this) }
``````

The first `this` refers to `maybeNull`, the second one refers to the result of `firstFunction()`, and `result` will be the result of `secondFunction()` (or null if `maybeNull` or any of the intermediate results were null).

A syntactic variation of `run()` is `let()`, which takes an ordinary function type instead of a function type with receiver, so the expression that might be null will be referred to as `it` instead of `this`.

Both `run()` and `let()` are also useful if you've got an expression that you need to use multiple times, but you don't care to come up with a variable name for it and make a null check:

``````val result = someExpression?.let {
firstFunction(it)
it.memberFunction() + it.memberProperty
}
``````

Yet another version is `with()`, which you can also use to avoid coming up with a variable name for an expression, but only if you know that its result will be non-null:

``````val result = with(someExpression) {
firstFunction(this)
memberFunction() + memberProperty
}
``````

In the last line, there's an implicit `this.` in front of both `memberFunction()` and `memberProperty` (if these exist on the type of `someExpression`). The return value is that of the last expression.

### `apply()` and `also()`

If you don't care about the return value from the function, but you want to make one or more calls involving something that might be null and then keep on using that value, try `apply()`, which returns the value it's called on. This is particularly useful if you want to work with many members of the object in question:

``````maybeNull?.apply {
firstFunction(this)
secondFunction(this)
memberPropertyA = memberPropertyB + memberFunctionA()
}?.memberFunctionB()
``````

Inside the `apply` block, `this` refers to `maybeNull`. There's an implicit `this` in front of `memberPropertyA`, `memberPropertyB`, and `memberFunctionA` (unless these don't exist on `maybeNull`, in which case they'll be looked for in the containing scopes). Afterwards, `memberFunctionB()` is also invoked on `maybeNull`.

If you find the `this` syntax to be confusing, you can use `also` instead, which takes ordinary lambdas:

``````maybeNull?.also {
firstFunction(it)
secondFunction(it)
it.memberPropertyA = it.memberPropertyB + it.memberFunctionA()
}?.memberFunctionB()
``````

### `takeIf()` and `takeUnless()`

If you want to use a value only if it satisfies a certain condition, try `takeIf()`, which returns the value it's called on if it satisfies the given predicate, and null otherwise. There's also `takeUnless()`, which inverts the logic. You can follow this with a `?.` to perform an operation on the value only if it satisfies the predicate. Below, we compute the square of some expression, but only if the expression value is at least 42:

``````val result = someExpression.takeIf { it >= 42 } ?.let { it * it }
``````

This material was written by Aasmund Eldhuset; it is owned by Khan Academy and is licensed for use under CC BY-NC-SA 3.0 US. Please note that this is not a part of Khan Academy's official product offering.