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
Top comments (0)