Kotlin Lambda Expressions

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!

Kotlin Functions – Making Kotlin More Modular

If you have had prior experience of programming language, you would be aware about functions.

Functions are a group of related statements which are designed to perform a specific task.

For example: a function to check if the entered number is even or odd.

Functions in kotlin are first class citizens and we declare them using the fun keyword.

Functions have 3 parts to be used effectively:

  • Declaration of Function
  • Definition of Function
  • Function Calling

Let’s have a look at what these mean to us and how to use them efficiently:

Declaration of Function

Defining the function syntax, the parameter it would accept and its return type is known as declaration of function.

Syntax:

fun functionName(<params list>) : Return Type

Example:

fun add(a: Float, b: Float): Float

In the above example, function add is accepting 2 inputs both of type float and return float.

Definition of Function

Definition in simple words means the body of the function.

Syntax:

fun functionName(<params list>) : <Return Type>{
	// Body of the Function
}

Example:

fun add(a: Float, b: Float): Float{
	var c : Float
	c = a+b
	return c
}

Calling Of Function

Function calling is pretty simple, by just passing the required number of parameters in the function name.

Syntax:

functionName(<params list>)

Example:

add(10.0,11.0)

After the parts of function, let’s understand the classification of functions in Kotlin.

Kotlin has various categories to classify function, it depends on the scope, usage, definition. Let’s have a look at the type of functions based on definition.

Types of Functions

  • Standard Functions / Built-in Functions
  • User Defined Functions

Let’s go through them individually:

Standard Functions

Functions which are predefined and can be used by the developers directly are known as standard functions.

Example: print(), max() and min() function.

These functions can be used directly by simply calling them.

User Defined Functions

Functions that a user can create or use in own project and give his own definition, like the add function we created above.

Let’s have a look below at how can we create User Defined Functions.

We can define a function using the fun keyword, followed by the function name and arguments.

fun functionName(){
	// Body of Function
}

Here, the function is created with functionName and empty parenthesis, which points the fact that function does not accept any arguments, to end inside the { } comes the body of the function.

Based on the above reading let’s try out a simple example which accepts name as input and prints a message as “Hello <Argument Value with Name>”.

fun main(args: Array<String>) {
   println("Calling function with Param : Kotlin Tutorial Blog")
   printWelcomeMessage("Kotlin Tutorial Blog ")
}

fun printWelcomeMessage(name : String){
	println("Hello $name!")
}

Output

Calling function with Param : Kotlin Tutorial Blog
Hello Kotlin Tutorial Blog !

Functions with Arguments

As seen in the example above, name is an argument or parameter which is being passed into the function, now let’s understand what can be two types of arguments: Formal Arguments and Actual Arguments.

Actual Parameters

Whenever we are calling the function, the actual variables which are passed are termed as Actual Argument or Actual Parameters.

Example:

fun main(args: Array<String>) {
	var message : String
	message ="Kotlin Tutorial Blog"   // here message variable is an actual parameter which is used in the function calling
   	printWelcomeMessage(message)
}

Formal Parameters

Now let’s see when the function is being defined:

Example:

fun printWelcomeMessage(name : String){
	// Here, name is termed as formal parameter 
	println("Hello $name!")
}

The parameters, like name in the example above which accepts the passed value from the functions calling are called formal arguments or formal parameters.

Points to Ponder in Case of Using Functions with Arguments

  1. The type of the argument needs to be mentioned explicitly. Like shown below:
fun add(num1:Integer, num2:Integer)

Here the type of numbers i.e. num1 and num2 are mentioned explicitly.

  1. We can separate two arguments by using comma (,).
  2. Data Type of Formal and Actual Parameters should be exactly same and should match in order of sequence also.

Having understood about the functions and the way functions works with arguments. That’s not all you can note that here function are not returning any value, which means that return type of the function is Unit. Unit is similar to void in Java which means that function doesn’t return any value, not even null.

Functions Returning Value

Lets move on further in User Defined functions and see how can we have a function which return some value. Below example is a simple program which will return the sum of 2 numbers using kotlin.

fun main(args: Array<String>) {
   val num1 = 15.5
   val num2 = 5.5
   val result: Int
   result = sum(num1, num2)
   println("Sum of 2 numbers: $num1 and $num2 is:- $result")
}

fun sum(value1: Double, value2: Double): Int {
    val sum = value1 + value2
    val sumInteger = sum.toInt()
    return sumInteger
}

Output

Sum of 2 numbers: 15.5 and 5.5 is:- 21

Here the point worth noting was the return type of the function sum. The sum function here was returning Int value.

How to make function return a value?

We can define functions which can return value by simply passing the data type of the expected value as shown in the example above. The syntax would look something as below:

fun functionName() : <Data Type of Return Value>{
	// Body Of Function
}

Single Expression functions

What if there are functions in the cases when the function have only single expression to be executed like below:

fun main(args: Array<String>) {
    println(printName("Kotlin", "Blog"))
}

fun printName(fName: String, lName: String): String = "Hello $fName $lName!"

Output

Hello Kotlin Blog!

Here, as you can see that we have removed curly braces { }  from the function body to provide to ease the code and make it look more simple.

In the case above since the expression evaluation can be done at the time of compilation it is evident that the return type of the function even if not mentioned explicitly can be worked upon by the system, like below:

fun main(args: Array<String>) {
    println(printName("Kotlin", "Blog"))
}

fun printName(fName: String, lName: String) = "Hello $fName $lName!"

The compilation of the above program gives the same output again:

Hello Kotlin Blog!

After having covered the basics of functions it’s important for us to understand other types of function which we will be using on daily basis.

Let’s understand the classification of function on the basis of scope of functions, unlike Java, Kotlin allows functions to be defined at the top level. Let’s see the different types functions based on the scope.

Functions Based on Scope

  1. Top Level Functions: These functions are placed on the top of the stack and are not needed to be enclosed inside a class.
  2.  Member Functions: Functions which can be defined inside a class.
  3. Local or Nested Functions: Functions defined inside a function.

Let’s see and understand them with examples one after the other.

Top Level Functions

As the name suggests, the functions which are defined directly and are not enclosed within a class are termed as Top Level Functions.

The most common example of Top Level Function is the main() functions,  we can place main function directly inside the file and it is not necessary to have it placed inside a class like java.

All the functions we have used above are Top Level Functions since those were not placed inside any class.

We can define the function directly inside the package and it can be used to call directly using the function name, in case when we want to call the package from outside we can simply do it calling packagename.functionName.

Member Functions

Functions which are defined inside the class and can be attributed as the property of class are termed as member functions.

We can access or call the member functions by using the object of the class.

They can be called using the dot (.) operator, for example : For an Employee class with object emp having function as displayEmployeeName() can be done as :

emp.displayEmployeeName()

We will discuss more about them when we will see class and object in upcoming tutorials.

Nested Functions

Kotlin allows you to define function inside functions and these can be accessed only inside the parent function. Such function are known as nested functions or local functions.

The use of having nested functions is to make code more encapsulated and make the program more readable and simple to understand. Interesting thing to know here is that we can use all the local variables of the outer functions.

The process of declaration and definition of all of these functions would remain same, the only difference is the place where the definition of function.

So, that was the basis of functions in Kotlin and we discussed about the main parts of kotlin and the basic function classification based on the definition of the function, well there’s still more to come as we have further interesting reads in terms of single line functions, anonymous functions, infix and recursive functions and lambda expressions. Stay tuned as we bring along those in the upcoming tutorials.

Kotlin return Statement

We have often encountered scenarios where we want to use a function to return a value, like say a function to return a Boolean if passed String contains special characters, this is what exactly we will try to understand in this tutorial. Kotlin is a simple way of doing it by using return statement.

Read more

Kotlin continue Statement

Jump statements are evident to us from the last topic in which we discovered the use of break condition which can be used with or without labels. This topic can be taken as an extension of the same. Break is a statement which is used to end or terminate the flow of control once it enters loop, but what if we want to keep on executing the flow but after skipping the current flow. Let’s take an example, for all students who are failing we have to grace marks if difference is less than 3, we don’t need to perform the calculation if the student is pass. Let’s have a look at syntax of continue to understand its working.

Read more

Kotlin break Statement

We have seen the usage of Flow of Control which allows us to quickly move apply conditions, now in this tutorial we will encounter the scenarios to be catered when the flow needs to be broken or redirected.

The way kotlin has given us some altered and improved for loop and a modern day switch which have reduced the developer’s effort, now let’s have look on topic without which no conditional flow can ever be truly complete, these are the break and continue.

Read more

Kotlin while and do while Loop

Before we discuss loops, let’s go back in time and remember those days when we used to be punished and teachers told us to write: “I will not repeat the same mistake” a 100 times. Understanding that pain and easing that effort programming languages came up with repeated conditional statements which ease the programming effort by simply reducing effort.

Read more

Kotlin for Loop

Before we jump on see what Kotlin has to offer in terms of for loop, let’s first recap the one we have used in Java.

A typical Java for loop would like below:

for (int i = 0;i<10;i++){
	System.out.println("Number is " + i);
}

Read more

Kotlin when Expression

If you are familiar with Java, then no course in Java is possible without flow of controls in which the switch forms a very important lesson. A typical switch looks like below:

switch(weekNumber){
       case 1:System.out.println(" MONDAY ");        break;
       case 2:System.out.println(" TUESDAY ");       break;
       case 3:System.out.println(" WEDNESDAY ");     break;
       case 4:System.out.println(" THRUSDAY ");      break;
       case 5:System.out.println(" FRIDAY ");        break;
       case 6:System.out.println(" WEEKEND ");       break;
       case 7:System.out.println(" WEEKEND ");       break;
       default:System.out.println(" NOT POSSIBLE "); break;
}

Read more

Kotlin if else Expression

In this tutorial you will learn about kotlin if, else and nested if else expression.

The if expression is definitely one of those constructs which lets us simplify our task of determining conditions during a program flow. Or rather, for performing any decisions in the program we look up to the if statement first, before considering any other because of our sheer familiarity with the statement and efficiency of the same. The latter part however, by and large depends on our problem statement. The if statement hence, is an integral part of any programming language.

Read more

Subscribe For Latest Updates

Signup for our newsletter and get notified when we publish new articles for free!