Kotlin — Function as a parameter

Md. Hasnain
LearnDroid
Published in
4 min readFeb 18, 2020

It’s fun when you can pass the fun into another fun as a parameter. Ow, fun means function :p . Every function in kotlin is a fun. And it’s really fun!

Kotlin — a great language to learn and use!

Do you know what’s happing in this following code?

fun add(a: Int, b: Int): Int = a + b
fun increment(a: Int): Int = a + 1
fun calc(a: Int, b: Int, perform: (a: Int, b: Int) -> Int) = perform(a, b)
fun calc(a: Int, perform: (a: Int) -> Int) = perform(a)
fun useFunctionAsParameter() {
val result = calc(1, 2, ::add)
val result2 = calc(result, ::increment)
Log.e(TAG, "1 + 2 = $result")
Log.e(TAG, "$result + 1 = $result2")
}

If you know then great! If not and you are interested about whats going on here then let’s explore more!

Recently I had do some works with a large codebase. For simplicity we were dividing the functions into smaller functions. Then somehow I faced the situation of calling different functions is going to need a bit more repeating code. Like, calling different functions in different confirmation dialog. Although the dialog is almost same but the functions I was calling after confirmation is a bit different. I came up with the idea of using a common interface with a common dialog for all. But, still it is a bit of code too and same code for every call. Then I went to the 2nd idea of passing the functions also. It was great and less of code. I did some searching and study also. Let’s share:

The simplest example:

This is the function we are going to pass as a parameter. The simplest one:

fun passMeAsParameter() {
Log.d(TAG, "I am the parameter function bro.")
}

This is the function where we will pass our function:

fun passAFunctionToMe(parameterFunction: () -> Unit) {
parameterFunction()
}

And finally this is how we use it:

fun useFunctionAsParameter() {
passAFunctionToMe(
{passMeAsParameter()}
)
}

Not that hard huh! In the last function we passed the passMeAsParameter() function as a function parameter. See the second braces. They are necessary. But looks like a bit..um..not so hot. Here lambda comes in handy.

fun useFunctionAsParameter() {
passAFunctionToMe {passMeAsParameter()}
}

There is another cooler way to do this:

fun useFunctionAsParameter() {
passAFunctionToMe(::passMeAsParameter)
}

Yap. Just two colons(::) makes it more fun!

Okay let’s make it a bit harder. This time we will write a whole function as a parameter.

fun useFunctionAsParameter() {
passAFunctionToMe(
{Log.d(TAG, "I am the parameter function bro.")}
)

}

Simple, isn’t it! Now, how about passing a parameter in the parameter function!

//function to pass
fun passMeAsParameter(log: String) {
Log.d(TAG, log)
}
//function with a function as a parameter
fun passAFunctionToMe(parameterFunction: () -> Unit) {
parameterFunction()
}
//now use the parameter function
fun useFunctionAsParameter() {
val log = "I am the parameter function bro.""

passAFunctionToMe(
{parameterFunction(log)}
)
}

With lambda:

passAFunctionToMe {passMeAsParameter(log)}

A bit more complex version with more fun:

//function to pass
fun passMeAsParameter(log: String) {
Log.d(TAG, "This is a $log")
}
//function with a String and a function as parameter
fun passAFunctionToMe(log: String, parameterFunction: (log: String) -> Unit) {
parameterFunction(log)
}
//now use the parameter function
fun useFunctionAsParameter() {
val log = "nice log""

passAFunctionToMe(
log, {parameterFunction(log)}
)

}

We don’t want to write same parameter twice. Let’s do this:

passAFunctionToMe(
log, {parameterFunction(it)}
)

Yes, you are right. “it” means that “log” will go there. With lambda it will be more beautiful:

passAFunctionToMe (log) {passMeAsParameter(it)}

But we don’t want to write “it” too.

passAFunctionToMe(
passAFunctionToMe (log, ::passMeAsParameter)
)

Again just two colons(::) makes it more fun!

Now let’s say, the function which we want to pass as parameter is in another class. No problem at all:

//another class
class AnotherClass {

//function to pass
fun passMeAsParameter() {
Log.d(TAG, "I am the parameter function bro.")
}
}
class MainClass {
//function with a function as a parameter
fun passAFunctionToMe(parameterFunction: () -> Unit) {
parameterFunction()
}
//now use the parameter function
fun useFunctionAsParameter() {
val anotherClass = AnotherClass()
passAFunctionToMe(anotherClass::passMeAsParameter)
}
}

Want to pass more than one function? Okay

//function with unlimited functions as parameter(Using vararg)
fun passManyFunctionsToMe(vararg functions: () -> Unit) {
functions.forEach { function -> function() }
}
//now use the parameter function
fun useFunctionAsParameter() {
passManyFunctionsToMe(::function1, ::function2, ::function3, ...)
}

Here I used vararg. You can use arrays, list or anything you want.

Your function has a return type? No problem:

fun add(a: Int, b: Int): Int {
return a + b
}
fun calc(a: Int, b: Int, perform: (a: Int, b: Int) -> Int): Int {
return perform(a, b)
}

fun useFunctionAsParameter() {
val result = calc (1, 2, { x: Int, y: Int -> add(x, y)})
Log.e(TAG, "1 + 2 = $result")
}

A more simpler (and b-e-a-uuuu-tiful) version of this code is:

fun add(a: Int, b: Int): Int = a + b

fun calc(a: Int, b: Int, perform: (a: Int, b: Int) -> Int) = perform(a, b)

fun useFunctionAsParameter() {
val result = calc(1, 2, ::add)
Log.e(TAG, "1 + 2 = $result")
}

That’s it! Now you know how to use function as a parameter. You will now also understand the code snipped we we were looking at the beginning of the tutorial. Kotlin is a very powerful language with many many awesome features. There are Coroutines, Android Extensions and many more! For now have fun with fun!

--

--

Md. Hasnain
LearnDroid

Programming is my hobby and Android is my passion :) . I am a professional Mobile Application Developer(Native and cross platform).