Kotlin Lambda Expressions and Higher-Order Functions

Kayvan Kaseb
Software Development
6 min readAug 19, 2022
The picture is provided by Unsplash

Basically, Kotlin is an expressive and concise programming language, which diminishes common code errors considerably and integrates into Android apps easily. As a result, it has been recommended firmly by Google for Android development. Furthermore, Kotlin functions are first-class that means functions can also be considered as data types. In other words, they can be stored in variables and data structures. This means it can be passed as arguments and returned from other higher-order functions. This article will provide you with some main concepts and best-practices in Kotlin lambda expressions and higher-order functions for Android developers.

Introduction and Overview

Basically, a function is a unit of code that performs a articular task. In programming languages, function is applied to break the code into smaller modules that makes the code more manageable and reusable. For instance, Kotlin functions are written using the fun keyword as follows:

fun double(x: Int): Int {
return 5 * x
}

In addition, a Kotlin function can be written as package-level function. So, there is no need to create a class to hold a function in all situations, which you can use it in other Object-Oriented languages, like Java. However, you should not ignore Single-Responsibility Principle (SRP) as a useful guidance in programming. Typically, we can be able to define a function as follows:

fun fun name(a: data_type, b: data_type, ...): return_type {
// Your codes
return
}

If a function does not return a value, its return type will be Unit. This value does not have to be returned explicitly (optional). Moreover, The Unit return type declaration in the function is optional.

An important point is that unlike in some programming languages, like Java, where a function can change the value passed into a parameter, parameters in Kotlin are immutable. You cannot reassign the value of a parameter from within the function body.

Fundamentally, Kotlin functions are first-class that means functions can also be considered as data types. In other words, they can be stored in variables and data structures. Additionally, it can be passed as arguments and returned from other higher-order functions. As a result, you can have an opportunity to do all operations on functions that are possible for other non-function values. For instance, you want the ability to change the behavior of a piece of your app at runtime or nest composable functions to build layouts on Android. This could be achieved by lambda expressions.

In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. Some programming language theorists require support for anonymous functions (function literals) as well. In languages with first-class functions, the names of functions do not have any special status; they are treated like ordinary variables with a function type.

Lambda Expressions

As mentioned earlier, Kotlin functions are also data types. Thus, you can store functions in variables. For instance, if we want to store a function in a variable, we can use simply one of the solutions as follows:

fun main() {
val trickFunction = sample
sample()
trickFunction()
}
val sample = {
println("Kotlin Functions")
}

The Kotlin compiler was able to infer that the value of sample was a function. So, Kotlin Functions will be printed as outputs twice. Nevertheless, if you want to determine the type of a function parameter or a return type, you will require to know the syntax for expressing function types.

Initially, lambda expressions are a type of function literal that means they are a function defined without using the fun keyword, and are used immediately as part of an expression. Therefore, since lambdas are not declared using the fun keyword, you can assign them simply to variables or pass them as function parameters. Lambda expressions offer a variety of ways to make your code more concise. The full syntactic form of lambda expressions is:

val lambda_name : Data_type = { argument_List -> code_body }

For example:

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

In Kotlin, the lambda expression syntax includes optional parts, except code_body. For instance, after removing the optional part for the previous example, we can see:

val sum = { x: Int, y: Int -> x + y }
  1. Lambda expressions are always surrounded by curly braces.
  2. If the return type of a lambda is not Unit, the last expression of the lambda body is considered as the return value.
  3. Parameter declarations in the full syntactic form go inside curly braces and have optional type parts.
  4. Parameter declarations and the lambda body must be separated by a ->

In fact, the most simple lambda expression that we could define would be like this:

val sampleLambda : () -> Unit = { println("Kotlin Function") }

Also, because there are no argument types to declare we can simplify this lambda even further as follows:

val sampleLambda = { println("Kotlin Function") }

Kotlin uses function types, such as (Int) -> String, for declarations that deal with functions: val onClick: () -> Unit = .... Function types help the compiler to evaluate the type of a lambda expression. Hence, in Kotlin programming, you have to have an explicit declare for the type of your lambda expression. If lambda returns no value, you can use it as Unit as mentioned earlier. Some examples for Lambda expressions with return type could be mentioned as follows:

val firstSample: (Int) -> Int = (a -> a * a)
val secondSample: (String,String) -> String = { a , b -> a + b }
val thirdSample: (Int)-> Unit = {print(Int)}

Besides, it is typical for a lambda expression to have just only one parameter. So, the parameter will be implicitly declared with it. In the following example [6, 8, 10] will be printed as output:

val numbers = arrayOf(-1, -2, -3, -4, 6, 8, 10)

fun main() {
println(numbers.filter { it > 0 })
}

Anonymous Functions

Notwithstanding the fact that the return type could be inferred from the Lambda expression automatically, it would be a requisite issue in some special situations. Thus, if you require to write it explicitly, you can use an alternative solution, which is called anonymous function. The body of this function could be either an expression or a block like a typical function. For instance:

fun(x: Int, y: Int): Int {
return x + y
}
fun(x: Int, y: Int): Int = x + y //Another syntax for the example

In fact, even though an anonymous function looks similar to a typical function declaration, its name is removed from declaration.

Higher-Order Functions

In Kotlin programming, a function can accept a function as parameter or can return a function, which is called Higher-Order function. This means instead of Integer, String or Array as a parameter to function, we can be able to pass anonymous function or lambda expression. In most situations, lambda expressions are passed as parameters in Kotlin functions. In the following example, we have invoked the higher-order function by passing the lambda expression as parameter in the main function:

var lambdafunc = {x: Int , y: Int -> x + y }

fun printSum( sample: (Int, Int) -> Int) {

var output = sample(10,20)
println("The sum is: $output")
}

fun main() {
printSum(lambdafunc)
}

Here, the sample is a local name to receive lambda parameter in the previous code. Finally, you can return a function from higher-order function in Kotlin. For instance:

fun higherfunc() : ((Int,Int)-> Int){
return ::sum
}
fun main() {

val sample = higherfunc()

val output = sample(10,20)
println("The sum is: $output")
}

In Conclusion

As you know, Kotlin has been recommended firmly by Google for Android development. Also, Kotlin functions are first-class that means functions can also be considered as data types. In other words, they can be stored in variables and data structures. This essay discussed some main concepts and best-practices in Kotlin lambda expressions and higher-order functions for Android developers based on JetBrains documents and resources.

--

--

Kayvan Kaseb
Software Development

Senior Android Developer, Technical Writer, Researcher, Artist, Founder of PURE SOFTWARE YAZILIM LİMİTED ŞİRKETİ https://www.linkedin.com/in/kayvan-kaseb