Kotlin Lambdas

Kotlin Lambdas

Lambda Expressions

Lambda expression or simply lambda is an anonymous function; a function without name. These functions are passed immediately as an expression without declaration. For example,

fun main(args: Array<String>) {

    val greeting = { println("Hello!")}

    // invoking function
    greeting()
}

When you run the program, the output will be:

Hello!

Here, a lambda expression is assigned to variable greeting. The expression doesn't accept any parameters and doesn't return any value in this program.

Then, the function (lambda expression) is invoked as:

greeting()

Example: Lambda With Parameters and Return Type

The program below has a lambda expression that accepts two integers as parameters, and returns the product of those two integers.

fun main(args: Array<String>) {
    val product = { a: Int, b: Int -> a * b }
    val result = product(9, 3)
    println(result)
}

When you run the program, the output will be:

27

Here, the lambda expression is:

Kotlin lambda expression syntax

Note, a lambda expression is enclosed inside curly braces.


Higher-Order Function

Koltin has a great support for functional programming. You can pass functions as arguments to other functions. Also, you can return a function from other functions. These functions are called higher-order functions.

Often, lambda expressions are passed to higher-order function (rather than a typical function) for convenience.


Example: Passing Lambda to Function

Let's pass a lambda expression to a higher-order function. Here's how you can do it.

fun callMe(greeting: () -> Unit) {
    greeting()
}

fun main(args: Array<String>) {
    callMe({ println("Hello!") })
}

When you run the program, the output will be:

Hello!

Here, callMe() is a higher-order function (because it takes function as a parameter). The greeting parameter accepts the lambda passed to the callMe() function as:

 greeting: () -> Unit

The empty parenthesis suggest that, the passed anonymous function doesn't accept any parameters. And, the Unit keyword suggest that the anonymous function doesn't return any value.


Lambdas are frequently used while working with collections. And, there are several built-in functions available in standard-library that take lambdas to make our task way easier. You will see couple of examples here:


Example: maxBy() Function

The maxBy() function returns the first element yielding the largest value of the given function or null if there are no elements.

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {

    val people = listOf(
            Person("Jack", 34),
            Person("Shelly", 19),
            Person("Patrick", 13),
            Person("Jill", 12),
            Person("Shane", 22),
            Person("Joe", 18)
            )

    val selectedPerson = people.maxBy({ person ->  person.age })

    println(selectedPerson)
    println("name: ${selectedPerson?.name}" )
    println("age: ${selectedPerson?.age}" )
}

When you run the program, the output will be:

Person(name=Jack, age=34)
name: Jack
age: 34

Here, maxBy() function takes a list of Person objects and returns the Person object having maximum age.


it Keyword: Used for Single Parameter

In the above program, the lambda expression accepts only one parameter (a list of Person objects). In such cases, you can refer the argument by using keyword it.

You can replace

val selectedPerson = people.maxBy({ person -> person.age })

with

val selectedPerson = people.maxBy({ it.age })

in the above program.


Example: maxBy() and startsWith() Function

The program below computes the maximum age of a Person object starting with letter S.

We will use two library functions maxBy() and startsWith() to accomplish this task. The starsWith() function returns true if it starts with the specified character passed as an argument.

data class Person(val name: String, val age: Int)

fun main(args: Array<String>) {

    val people = listOf(
            Person("Jack", 34),
            Person("Shelly", 19),
            Person("Patrick", 13),
            Person("Jill", 12),
            Person("Shane", 22),
            Person("Joe", 18)
            )

    val selectedPerson = people
            .filter { it.name.startsWith("S") }
            .maxBy{ it.age }


    println(selectedPerson)
    println("name: ${selectedPerson?.name}" )
    println("age: ${selectedPerson?.age}" )
}

When you run the program, the output will be:

Person(name=Shane, age=22)
name: Shane
age: 22

Recommended Readings

  • Kotlin Closures
  • Kotlin With and apply