Kotlin: Function type, Function literal, Lambda expression and Anonymous function
Sagar
Posted on May 1, 2020
Function Type
We know data types. Similarly, we have function type too in kotlin.
Signature / Syntax
Name: (only comma separated data types) -> return data type
ft: (Int, Int) -> Int
How to call / execute a function type?
ft(1, 2)
//OR
ft.invoke(1, 2)
Usage:
Function type as an interface
Like an interface, we can implement a function type in a kotlin class. When we implement a function type, we get a method called “invoke” to override having a similar signature of the implemented function type.
Example:
//Implementing a function type like an interface
class ClassName : (Int, Int) -> Int {
/**We get a method "invoke" to override with similar signature of
* function type we implemented
*/
override fun invoke(p1: Int, p2: Int): Int {
return p1 + p2
}
}
Function type as a parameter
As a function parameter in a higher order function. The function that takes one or more function types as a parameter/s or/and the function that returns a function type is known as a higher order function.
fun doSomething(a: Int, b: Int, ft: (Int, Int) -> Int): String {
val result = ft(a, b) //OR ft.invoke(a, b)
return “doSomething: ” + result
}
There is one thing to remember here:.
A new function object will be created for each and every function type of a higher order function.
How to call/use/execute such a higher order function?
We know how to call a function but we may not know how to pass a function type argument/s in any higher order function!
We can pass function type arguments using function literal, lambda expression or by anonymous function. Let us check these all one by one.
Function literal
Signature / Syntax: 1
{ comma separated pascal parameters -> business logic }
Example:
{ x: Int, y: Int -> x + y }
Note that the last statement in a function literal is considered as a return statement. So, the last statement in a function literal decides the return type.
We can use function literal to pass as a function type argument for higher order function as below:
//Calling a higher order function
println(doSomething(1, 2, {x: Int, y: Int -> x + y}))
//prints: doSomething: 3
OR if the function type parameter is the last parameter in the higher order function, we can write our function literal after the closing function parenthesis as below:
//Calling a higher order function
println(doSomething(1, 2){x: Int, y: Int -> x + y})
//prints: doSomething: 3
OR if the higher order function has only one parameter or say if the function type parameter is one and only parameter in a higher order function like below:
//region A higher order function that has one and only function type parameter
private fun doSomething(ft: (Int, Int) -> Int) {
val result = ft(1, 2)
/*...*/
}
//endregion
While calling such a higher order function, we can omit the function call parentheses like below:
doSomething { x: Int, y: Int -> x + y }
Syntax / Signature 2
Also, if the function type is only parameter in a higher order function and if the function type has also only one parameter like below:
private fun doSomething(ft: (Int) -> String) {
/*...*/
}
While passing such a function literal, in addition to function call parentheses, we can also omit the parameter and an arrow ->
! We just write core business logic between curly braces and we can access our single parameter through the keyword it like below:
doSomething { "$it" }
And if the higher order function has only one function type parameter and the function type has no parameter like below:
private fun doSomethingY(ft: () -> String) {
/*...*/
}
We can simply write our business logic between curly braces right after the higher order function name as below:
doSomethingY { "test" }
Types:
There are two types of function literals.
Lambda expression
Anonymous function
Lambda expression
Lambda expression is just another way to define a function in a short way.
Signature / Syntax 1
We can either specify explicit function type and let the data type of parameters inferred in below format:
nameOfTheLambda: (explicit function type) = { comma separated parameter: Inferred data type -> business logic }
Or we can give explicit type annotation to parameters and let the function type inferred like below format:
nameOfTheLambda: (inferred function type) = { comma separated parameter: Explicit dataType -> business logic}
Or we can write both function type and data type of parameter (but why?) like below:
nameOfTheLambda: (explicit function type) = { comma separated parameter: Explicit dataType -> business logic}
Let us see an example:
/**
* nameOfTheLambda: function type
* = { comma separated pascal parameters -> business logic }
*/
val lambda: (Int, Int): Int = { x: Int, y: Int -> x + y }
Signature / Syntax 2 for special case
If a lambda has only one parameter, we can omit everything except a business logic inside the curly braces and we can access the single argument using the keyword: it
Example:
Suppose we have a lambda expression like below:
val lambdaIncrement: (Int): Int = { x: Int -> x + 1 }
We can write the equivalent lambda as below:
val lambdaIncrement: (Int): Int = { it + 1 }
Summary for a lambda expression having a single parameter
Usage: How to call / execute / use lambda expression
We can use above lambda expression directly like below:
println(lambda(1,2)) //prints: 3
OR we can pass a lambda as a function type argument to a higher order function like below:
println(doSomething(1, 2, lambda)) //prints: doSomething: 3
Sometimes, the common term “lambda” is used to represent a function type, function literal or a lambda expression.
Anonymous function
Signature / Syntax
//fun(comma separated pascal parameters) = business logic
fun(x: Int, y: Int) = x + y
We can store an anonymous function in a variable like below:
val anonymousFunction: (Int, Int): Int = fun(x: Int, y: Int) = x + y
Usage: How to use an anonymous function
We use an anonymous function as an argument for a higher order function like below:
println(doSomething(1, 2, fun(x: Int, y: Int) = x + y ))
//prints: doSomething: 3
We can use an anonymous function through a variable to pass as an argument in a higher order function as below:
println(doSomething(1, 2, anonymouseFunction)
//prints: doSomething: 3
That’s all! If you have read this article, if you find this article helpful, you can click on that heart icon 😉
Applauds and creative critics are always welcome 😇
In next article, we will learn about Extension function and Receiver type.
Thanks for reading the article! Have a great day 😇
Let us be Connected
https://www.linkedin.com/in/srdpatel
Tags: kotlin, function type, function literal, lambda expression, anonymous function, higher order function
Posted on May 1, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.