This post is about Higher Order Functions in Kotlin.
One of the cool thing about Kotlin is; it has support of functional programming as well. That means kotlin functions can be stored in a variable, passed to other function as argument and also can be returned from a function.
Table of Contents
What are Higher Order Functions in Kotlin?
As I said in Kotlin we can store functions in variables, we can pass them as argument to other functions and we can also return function from a function. When we define a function that accepts a function as an argument or returns a function from it we call it a Higher Order Function.
Sounds confusing? 😉
Here is an example for you.
Defining a Higher Order Function
Here is a simple Higher Order Function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//A simple Higher Order Function in Kotlin //This function accepts three parameters //And the last parameter is a function fun rollDice( range: IntRange, time: Int, callback: (result: Int) -> Unit ) { for (i in 0 until time) { val result = range.random() //As the last parameter is a function //we can call it as a function callback(result) } } |
Let’s understand the third parameter in the above given function.
The above picture explains, how you can define function as a parameter. Now we will try to call this function.
Calling a Higher Order Function
Now, let’s call our higher order function.
1 2 3 4 5 6 7 |
fun main() { rollDice(1..6, 3, { result -> println(result) }) } |
We will get the following output.
1 2 3 4 5 |
1 6 1 |
Let’s understand how we pass a function as a parameter.
In the above picture we are using the following snippet to pass the third parameter for the function rollDice()
1 2 3 4 5 |
{ result -> println(result) } |
And this is called a lambda expression. And we can even store it to a variable.
1 2 3 4 5 |
val a: (result: Int) -> Unit = { result -> println(result) } |
Trailing Lambda
In our example, the function rollDice()Â is the higher order function that is accepting another function as an argument. And the function that we have defined as the argument is the last parameter. When we have this situation, we can put the lambda expression outside the parenthesis while calling the function.
1 2 3 4 5 6 7 |
fun main() { rollDice(1..6, 3) { result -> println(result) } } |
Looks cool right?
it Keyword
Another interesting thing is, when we have only a single parameter in our lambda expression, we can omit the parameter name and instead of writing a name we can use it keyword to get the parameter.
1 2 3 4 5 6 7 |
fun main() { rollDice(1..6, 3) { println(it) } } |
Another cool feature correct?
Now, another interesting thing I would like to tell is; when your function is having only a single parameter that is a function, in this case you can even omit the parenthesis.
1 2 3 4 5 6 7 8 9 10 11 |
fun rollDice(callback: (result: Int) -> Unit) { callback((1..6).random()) } fun main() { rollDice { println(it) } } |
Assigning null as the default value
We can also assign null as the default value.
1 2 3 4 5 6 7 8 9 10 11 |
fun rollDice(callback: ((result: Int) -> Unit)? = null) { callback?.invoke((1..6).random()) } fun main() { rollDice { println(it) } } |
When you have null as the default value, you can use invoke()Â to call the function.
Awesome right? Or you are still confused?
If you are still confused, you might be thinking that why to make things complicated. But trust me it is a very handy and useful thing.
Imagine a scenario when you are doing some heavy operation (that requires long time to execute) in a different thread inside a function. And after finishing that task you need a callback. You can achieve this thing very easily using higher order functions in kotlin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
fun rollDice(callback: ((result: Int) -> Unit)? = null) { println("Roll Dice Started") thread { //mimicking a heavy operation //by just putting a Thread.sleep Thread.sleep(5000) //function was already finished //but after 5 seconds //we will get a callback at the trailing lambda callback?.invoke((1..6).random()) } println("Roll Dice Ended") } fun main() { rollDice { println(it) } } |
Try running this code in your machine.
So that’s all for Higher Order Functions in Kotlin. In case you have some inputs to improve this post, then please comment it below. Questions are welcome. Please share this post with your friends if you think it was useful. Thank You.