
In this article, we will explore higher order functions in Kotlin with examples.
Prerequisites:
- Lambdas and Anonymous Functions
- Basics of Kotlin
In the function literals tutorial, we have seen how to assign functions to the variables. Now, we will see how to pass a function to another function.
Higher Order Function in Kotlin:
It is a function that takes a function as a parameter or returns a function or both. In general, lambda expressions are passed as an argument to a higher-order function or returned from it. We can also use anonymous functions for the same. Let’s understand them with examples.
Passing Lambda Expression as a Parameter:
Example:
private fun hof(addition: (Int, Int) -> Int) {
}
Here, hof() is a higher-order function because it takes a function as a parameter. Let’s see how the parameter is structured.
addition: (Int, Int) -> Int
Here, addition is just the name of the parameter. It can be any name.
(Int, Int) represents that it takes two integers.
Int represents that it returns an integer.
When we call hof(), we have to pass a lambda that takes two integers and returns an integer. Let’s do that.
val add = { a: Int, b: Int -> a + b }
hof(add)
In the first statement, we have created a lambda expression that takes two integers and returns the addition of them.
Next, we have called hof() by passing the lambda.
Now, inside hof(), let’s invoke addition and print the result.
private fun hof(addition: (Int, Int) -> Int) {
val result = addition(10, 20)
println(result)
}
Here is the complete code:
fun main() {
val add = {a: Int, b: Int -> a + b }
hof(add)
}
private fun hof(addition: (Int, Int) -> Int) {
val result = addition(10, 20)
println(result) // prints 30
}
When we call addition(10,20), the lambda add will be invoked with a = 10 and b = 20. The add returns the sum of the two numbers. We assigned it to the result. When we print the result, we will see 30 in the console.
Note: We can directly pass the lambda expression without creating the variable.
Example:
fun main() {
hof( { a: Int, b: Int -> a + b } )
}
There are two cases where we have to move the lambda argument out of parentheses.
Case 1: When lambda is the only argument.
Our hof() accepts only one argument which is a lambda. So, let’s move the lambda out of parentheses.
fun main() {
hof { a: Int, b: Int -> a + b }
}
Case 2: If the lambda is the last argument.
For example, look at the following method.
private fun hof2(num1: Int, addition: (Int, Int) -> Int) {
}
It takes two parameters num1 and addition. Let’s call this function.
fun main() {
hof2(num1 = 10, { a: Int, b: Int -> a + b })
}
Since the lambda is the last argument, we can move it out of the parentheses.
fun main() {
hof2(num1 = 10) { a: Int, b: Int -> a + b }
}
“it” in Lambda:
If a lambda expression has only one parameter, we can omit the parameter along with ->. We can access the parameter using it identifier.
Example:
fun main() {
hof3 { println("Hi, $it") }
}
private fun hof3(greet: (String) -> Unit) {
greet("John")
}
hof3() method accepts a function that has only one parameter. So, when we call it (inside the main()), we have omitted the parameter and ->. We can access the string using it. If you are using IntelliJ or Android Studio, you can see the it.

Lambda can be a return value.
Example:
fun main() {
val message = hof4()()
print(message) // prints Hi
}
private fun hof4(): () -> String {
val lambda = { "Hi" }
return lambda
}
Here, hof4() is a higher-order function that returns a function. Look at the return type.
() -> String
() represents that it takes no parameter
String represents that it returns a string.
This is what exactly we have done inside hof4(). We have created a lambda that takes no parameters and returns a string.
Inside the main(), we have called hof4(). Note that hof4() returns the lambda whereas hof4()() returns the string “Hi”. We are storing the string in the message and printing the value.
Passing Anonymous Function as a Parameter:
Let’s pass an anonymous function to our hof().
fun main() {
val add= fun(a: Int, b: Int): Int {
return a + b
}
hof(add)
}
private fun hof(addition: (Int, Int) -> Int) {
val result = addition(10, 20)
println(result) // prints 30
}
Inside the main(), we have created an anonymous function that takes two integers and returns the addition of them. We have passed it to hof().
When we call addition(10,20), the anonymous function will be called with a = 10 and b = 20. It returns the sum of the two numbers. We assigned it to the result. When we print the result, we will see 30 in the console.
An anonymous function can be a return value.
Example:
fun main() {
val message = hof4()()
print(message) // prints Hi
}
private fun hof4(): () -> String {
val messageFun = fun():String {
return "Hi"
}
return messageFun
}
Inside hof4(), we have created an anonymous function (messageFun) that takes no parameters and returns a string. We are returning it.
Inside main(), we have called hof4(). Note that hof4() returns the function whereas hof4()() returns the string “Hi”. We are storing the string in the message and printing the value.
Higher order functions can also return regular functions.
Example:
fun main() {
val message = hof4()()
print(message) // prints Hi
}
// Regular function
private fun messageFun(): String {
return "Hi"
}
// Higher order function
private fun hof4(): () -> String {
return ::messageFun
}
Inside hof4(), we have added :: before messageFun. It represents function reference. We use it whenever we want to pass or return a function.
Here is the example of passing a regular function to higher order function:
fun main() {
hof5(::messageFun)
}
// Regular function
private fun messageFun(): String {
return "Hi"
}
// Higher order function
private fun hof5(messageFunction: () -> String) {
val message = messageFunction()
println(message) // Hi
}
Note that inside hof5(), we are using messageFunction(), not messageFunction()(). This is because messageFunction represents a function. So, when we call it using messageFunction(), messageFun() will be called and “Hi” will be returned.