Having seen through functions, we have seen a variety of them having varied flavours. In this article here we would be going through functions which are of anonymous type but can be treated as values. By this we mean that we can pass them as arguments to fetch a value, return them directly from a function or in simple words, and treat them as a normal object.
Lambdas are not unique programming concept and have been there for quite some time having their implementations in different languages.
Kotlin Lambdas
Definition
Lambdas are function literals which denotes the functions that are not declared but passed on immediately as expressions. We use Lambdas to make our code simpler and compact.
Syntax
val lamdbaFun : data_type = { arguments -> action }
As per the above syntax, lamdbaFun is the name which we giving to our lambda function. The naming convention for lambda remains similar to any function. We also mention the data type of the return value to be returned by the function. The data type of return can be left blank as well, since the kotlin compiler can derive it out during compilation time of the function.
Let’s have a look at the most basic lambda expression which neither accepts an input nor does return any value as shown in below example:
fun main(args: Array<String>) { // Declaring Lambda Function with name : printMessage val printMessage = { println("Hello World! ")} // Calling function : Print Message printMessage() }
Output:
Hello World!
In the above example “printMessage” is a lambda expression which is neither accepting an argument nor returning any value.
Let’s see how we can have a function which accepts two input of type integer and returns the sum of two number.
fun main(args: Array<String>) { // Calling function: Calculate SUM print ("The sum of number is $sum (10,20)") } // declaring Lambda Function with name: sum which accepts integer a & b as input // and returns the sum as output. val sum = { a: Int , b : Int -> a + b }
In the example above we have created a function to calculate the sum, but if you look carefully there’s no return type of the function mentioned. The compiler automatically picks up the return type.
Now let’s have a look at the example below which prints the square of a number as a String.
fun main(args: Array<String>) { print("The square of number is: "+ square(2)) } val square = { num : Int -> val output = num * num output.toString() }
In the above example we have created the function to return a string and the same is passed back. The output of the above code is:
The square of number is: 4
Till now we have covered the basic lambda expressions, let’s have a look at tweaked versions of lambdas which can be used in different ways:
Lambdas with when
Yes, we agree lambdas are single expression based functions and so are when which can be used in case of switch in kotlin. We can use when in the lambdas, since when also form a single expression:
fun main(args: Array<String>) { print("Grade for student with marks 95 is: "+compileGrade(95)) } val compileGrade = { marks : Int -> when(marks) { in 0..40 -> "C" in 41..70 -> "B" in 71..80 -> "A" in 81..90 -> "A+" in 91..100 -> "A++" else -> false } }
In the above example the entire when block is treated as a single expression and the output of the above code is as below:
Grade for student with marks 95 is: A++
Lambdas Using the ‘it’ keyword
In cases when lambda functions are accepting multiple elements of the same type and there is an operation to be performed on each one of them, we can do it by using ‘it’ operator. It operator would reduce the need to pass the input argument and can be directly used with ‘it’ operator.
Let’s see how we can implement it in coding:
fun main(args: Array<String>) { val arr = arrayOf(1,2,3,4,5) print("Employee Code when using Regular Lambda Expressions") // Regular/ long hand lambda expressions arr.forEach { num -> println("EMP000"+num) } print("Employee Code when using Short Hand Lambda Expressions") // Short Hand Lambda Expressions arr.forEach { println("EMP000"+it) } }
The output of the above code is like:
Employee Code when using Regular Lambda Expressions
EMP0001
EMP0002
EMP0003
EMP0004
EMP0005
Employee Code when using Short Hand Lambda Expressions
EMP0001
EMP0002
EMP0003
EMP0004
EMP0005
In the above example, ‘it’ represents the each element of the array.
High-Order Functions & Lambdas
Kotlin supports functional programming. Kotlin provides the ability to pass functions as arguments to other functions. Also, kotlin functions have ability to return functions from other functions, these functions are referred as higher order functions. Kotlin has provided us with several built in functions which are available in standard library and accept arguments as lambdas.
Lets see an example of these functions by using lambdas in functions while working over collection. In the example below we are taking an example of function to find the employee with the highest salary.
data class Employee(val name: String, val sal: Int) fun main(args: Array<String>) { val employeeList = listOf( Employee("Ram Mohan", 5000), Employee("Rohit Aryan", 6200), Employee("Hello World", 5100), Employee("New Employee", 5150), Employee("Sachin", 5950), Employee("Ramesh", 4950) ) val maxSalEmp = employeeList.maxBy({ emp -> emp.sal }) println(maxSalEmp) println("Name Of Employee With Maximum Salary: ${maxSalEmp?.name}" ) println("Maximum Salary od Employee : ${maxSalEmp?.sal}" ) }
The output of the above code would be like:
Employee(name=Rohit Aryan, sal=6200)
Name Of Employee With Maximum Salary: Rohit Aryan
Maximum Salary od Employee : 6200
So, how it exactly happened?
We created a data class as Employee which has 2 properties i.e. name and salary, for the sake of simplicity we have taken salary type as int. Now, we make a list of employees and store it inside a variable as “employeeList”. On this list we are calling a function “maxBy” which accepts the condition to be tested as lambda expression. That’s it, the work is done. We got the employee with maximum salary in the variable “maxSalEmp”.
The variable maxSalEmp is like just another Employee object class having the details of employee with the maximum salary.
We can even use the multiple functions in one case like shown in the example below:
data class Employee(val name: String, val sal: Int) fun main(args: Array<String>) { val employeeList = listOf( Employee("Ram Mohan", 5000), Employee("Rohit Aryan", 6200), Employee("Hello World", 5100), Employee("New Employee", 5150), Employee("Sachin", 5950), Employee("Ramesh", 4950) ) val maxSalEmp = employeeList .filter { it.name.startsWith("R")} .maxBy { it.sal } println(maxSalEmp) println("Name Of Employee starting with R and having Maximum Salary: ${maxSalEmp?.name}" ) println("Name Of Employee starting with R with Maximum Salary od Employee : ${maxSalEmp?.sal}" ) }
In the above example, we have first used filter and the based on the filtered value we are checking the maximum salary.
The output of the above code is as below:
Employee(name=Rohit Aryan, sal=6200)
Name Of Employee starting with R and having Maximum Salary: Rohit Aryan
Name Of Employee starting with R with Maximum Salary od Employee: 6200
So, that was all about the Kotlin lambdas we just referred above, one of another major application of Lambdas function is the onClick() which we use in Android. Now, its time to put on your thinking cap and use lambdas there. Till then Happy Coding!