Kotlin High Order Functions and Lambdas Explained

A higher-order function is a function that takes functions as parameters or returns a function. Instead of Integer, String, or Array as a parameter to a function, we will pass anonymous function or lambdas. Frequently, lambdas are passed as parameters in Kotlin functions for convenience.


before getting started into scope functions, I have explained the basics of kotlin in detail.

Beginning Android Development with Kotlin

Kotlin Scope Functions Explained

koin – Kotlin Dependency Injection In Android

Ktor – Networking Client For Android


This can be achieved by using lambda expressions or function references.

Function Types

Kotlin uses function types to represent the type of a function.

The syntax of a function type is,

(Type, Type) -> ReturnType

with the left side containing the parameter types and the right side the return type. For empty returns, you can use Unit.

Function types can be instantiated in a multitude of ways. Let’s look at some of them.

  • Lambda expressions
  • Anonymous functions
  • Existing function

Lambda expressions

The full syntactic form of lambda expressions is as follows:

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
  • A lambda expression is always surrounded by curly braces.
  • Parameter declarations in the full syntactic form go inside curly braces and have optional type annotations.
  • The body goes after the ->.
  • If the inferred return type of the lambda is not Unit, the last (or possibly single) expression inside the lambda body is treated as the return value.

If you leave all the optional annotations out, what’s left looks like this:

val sum = { x: Int, y: Int -> x + y }

It’s very common for a lambda expression to have only one parameter.

If the compiler can parse the signature without any parameters, the parameter does not need to be declared and -> can be omitted. The parameter will be implicitly declared under the name it:

ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'

Returning a value from a lambda expression

You can explicitly return a value from the lambda using the qualified return syntax. Otherwise, the value of the last expression is implicitly returned.

Underscore for unused variables

If the lambda parameter is unused, you can place an underscore instead of its name:

map.forEach { _, value -> println("$value!") }

Anonymous functions

An anonymous function looks very much like a regular function declaration, except its name is omitted. Its body can be either an expression (as shown above) or a block:

Anonymous functions as an expression

fun(x: Int, y: Int): Int = x + y

Anonymous functions as a block.

fun(x: Int, y: Int): Int {
    return x + y
}

Existing function

Member functions, top-level functions, or extension functions can be used as an instance of a function type. As an example, getting a reference to the String. Any other function declarations, even constructors can be used.

val filter = String::filter

Higher Order Functions

A higher-order function is a function that takes functions as parameters or returns a function.

It’s a function that can take do two things:

  • Can take functions as parameters
  • Can return a function

We will see both the thing one by one.

Take functions as parameters

fun getUserDetail(user: () -> Unit) {
        ...
        user()
    }

function getUserDetail takes user: () -> Unit .

user is just the name for the parameter. It can be anything. We just need to use this when we execute the function.

() -> Unit, this is important.

() represents that the function takes no parameters.

The unit represents that the function does not return anything.

So, the getUserDetail can take a function that takes zero parameters and does not return anything.

Let’s try the getUserDetail function without arguments.

fun main() {
   
    fun getUserDetail(user: () -> Unit) {
       user()
       println("Address: chennai")
    }
   
   getUserDetail({
	println("name : joe")
    println("age : 25")
})
}

next, we can see the same function getUserDetail with arguments.

fun main() {
   
    fun getUserDetail(user: (String, Int) -> Unit) {
       user("joe", 25)
       println("Address: chennai")
    }
   
   getUserDetail({name, age ->
	println("name : joe")
    println("age : 25")
})
}

function getUserDetail(user: (String, Int) -> Unit)

(String, Int) – represent the functions takes two arguments.

The Unit represents that the function does not return anything.

A function can return a function

We can return a function from a higher-order function. While returning the function, we have to specify the parameter types and return type of regular function in the return type of the higher-order function.

fun main() {
   
    fun getUserDetail() : ((String) -> Unit) {
       
        return ::getUser
    }
    
    
   val userDetail = getUserDetail()
   userDetail("john")
}

fun getUser(name: String) : Unit {
        println(name)
    }

function fun getUserDetail() : ((String) -> Unit)

: (String) – represent the return functions takes one arguments.

: () -> Unit– the Unit represent the function return nothing.

::getUser – represents the function return getUser function.

In main function, we have called the higher function which returns another function and store this in a variable userDetail .

val userDetail = getUserDetail()
userDetail("john")

then we invokes the userDetail() function using local variable userDetail(“john”) by passing one arguments.

Leave a Reply

Your email address will not be published. Required fields are marked *