Kotlin: Lambda Expressions and Higher-Order Functions

Divyasourabh
The Startup

--

Kotlin, as a statically typed programming language. This means the type of a variable is known at compile-time instead of at run-time.

Kotlin functions are the First-Class Function. 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.

First-class functions are a necessity for the functional programming style, in which the use of higher-order functions is a standard practice.

Lambda Expressions

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 an -> sign. 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.

Lets say function which takes two int as the parameters, adds them, and returns as an int this we can achieve by two ways:

Without Lambda Expressions

fun addTwoNumber (a: Int , b: Int) : Int {
return a+b
}

val sumOfTwoNumber = addTwoNumber (2,3)

With Lambda Expressions

val sumOfTwoNumber : (Int, Int) -> Int = { a: Int, b: Int -> a + b }

Lambda expressions and anonymous functions are ‘function literals’, i.e. functions that are not declared, but passed immediately as an expression. They provide us a compact way of writing code.

Higher Order Functions

Higher-order function is a function that takes functions as parameters or returns a function. Passing lambda expression as a parameter to Higher-Order Functions.

Some of the basic higher-order functions are apply, with, let, also, and run etc. in Kotlin’s standard library.

Example 1: Pass Lambda expression inside a higher order function as parameter

fun main(args: Array<String>) {
// Passing function body as a Lambda expressions
printStr({println("fun body passed as a Lambda expressions")})
}

// Body of this method pass by calling function here i.e println()
fun printStr(printingString: () -> Unit) {
printingString()
}

Example 2: Assign Lambda Expression to variable and pass variable as a parameter

// lambda expression
var lambdaExpression = { println("Sample String to be print") }

// higher-order function
fun higherOrderfunc( lambdaFuncParam: () -> Unit ) {
lambdaFuncParam() //invokes lambda expression
}

fun main(args: Array<String>) {
//invoke higher-order function
// passing lambda expression variable as parameter
higherOrderfunc (lambdaExpression)
}

Explanation:

Lambda Expression store into var variable name lambdaExpression which pass as a argument in higherOrderfunc() which accepting function as parameter lambdaFuncParam ( lambdaFuncParam is just the name for the parameter. It can be anything, We just need to use this when we execute the function ) and Unit represents that the function does not return any value.

Example 3: Function accept two parameter of Integer type and return Addition of both integers, that function pass as a parameter

// regular function definition
fun addTwoNumbers(a: Int, b: Int): Int{
var sum = a + b
return sum
}
// higher-order function definition
fun higherfunc(addfunction:(Int,Int)-> Int){
// invoke regular function using local name
var result = addfunction(3,6)
print("The Addition of a and b numbers is: $result")
}
fun main(args: Array<String>) {
// invoke higher-order function
higherfunc(::addTwoNumbers)
}

Above three examples explain the case when functions as parameter. Now discuss another case i.e returning a function.

Returning a function from 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.

Lets understand which an example:

we define addition() function which accepts two integer parameters and its return type is also an integer. Then, we define the higher-order function having return type as a function.

// function declaration
fun addition(a: Int, b: Int): Int{
return a*b
}
//higher-order function declaration
fun higherfunc() : ((Int,Int)-> Int){

// ::addition return addition() function reference
return ::addition
}

fun main(args: Array<String>) {

// invoke function and store the return function into a variable
val sumOfTwoNumber = higherfunc()

// invokes the addition() function by passing 2,4 arguments
val result = sumOfTwoNumber(2,4)
println("The addition of two numbers is: $result")
}

Advantages of Using Higher Order Functions

  • Higher Order functions helps reduce the code redundancy by allowing the common code functionality to be passed as a function to another function.
  • Increases readability of the code.

Bonus!!

Higher order functions in JAVA

Before Java8, we used to pass a function to a function with the help of anonymous inner classes, but now we do that with the help of Lambdas.

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me.

Other Useful Links

--

--