Inline Functions in Kotlin

Deepak Sikka
4 min readJun 22, 2021

This Story is from the Kotlin- Series, In this article we will learn inline functions in Kotlin.

In Kotlin, the higher-order functions or lambda expressions, all stored as an object so memory allocation, for both function objects and classes, and virtual calls might introduce runtime overhead.Sometimes we can eliminate the memory overhead by inlining the lambda expression.

What is inlining ?

Inlining is basically requesting the compiler to copy the (inlined) code at the calling place.In order to reduce the memory overhead of such higher-order functions or lambda expressions, we can use the inline keyword which ultimately requests the compiler to not allocate memory and simply copy the inlined code of that function at the calling place.

Why it is required ?

When a program is executed and a function is called, CPU stores the memory address of the instruction following the function call, copies the arguments of the function into a stack and finally transfers control to the specified function. The CPU then executes the function code, stores the function return value in a predefined memory location/register and returns control to the calling function.

fun higherfunc(str : String, mycall :(String)-> Unit) {

// inovkes the print() by passing the string str
mycall(str)
}

// main function
fun main() {
print("GeeskforGeeks: ")
higherfunc("A Computer Science portal for Geeks",::print)
}

What inline keyword will do in the above program?

inline fun higherfunc(str: String, myCall: (String) -> Unit) {

// inovkes the print() by passing the string str
myCall(str)
}

// main function
fun main() {
print("GeeskforGeeks: ")
higherfunc("A Computer Science portal for Geeks", ::print)
}

With the help of the inline keyword, the println lambda expression is copied in the main function in the form of System.out.println and no further calls required.

Non-Local control Flow :

In Kotlin, if we want to return from a lambda expression then the Kotlin compiler does not allow us to do so. With the help of the inline keyword, we can return from the lambda expression itself and exit the function in which inlined function is called.

var lambda1 = {
println("\n Lambda expression")
return
}

Output:

Error:(4, 5) Kotlin: 'return' is not allowed here

Kotlin Program of Using Return in Lambda While Passing as an Argument to Inlined Function:

var lambda1 = {
println("\n Lambda expression")
}
var lambda = {
println("\n Lambda rotation")
}

// inlined function
inline fun inlinedFunc(lmbd1: () -> Unit, lmbd2: () -> Unit) {
lmbd1()
lmbd2()
}

fun main() {
print("GeeskforGeeks: ")
higherfunc("A Computer Science portal for Geeks", ::print)
// lambda()
//lambda1()

println
("Main function starts")
inlinedFunc(
{
println("Lambda expression 1")
return
},
// inlined function allow return
// statement in lambda expression
// so, does not give compile time error

{ println("Lambda expression 2") })

println("Main function ends")
}

Explanation: Here, we passed two lambda expressions as arguments to the inlinedFunc() function. While calling the inlined function from the main, we pass both as to its arguments. In the inlined function, lmbd1() invoked the first expression and return keyword force the lambda expression itself and the main function from where it is called to exit.

crossline keyword :

In the above program, return in lambda exits the inline function as well as its enclosing function. So to stop returning from the lambda expression we can mark it using the crossline. It will throw a compiler error if sees any return statement in the Lambda expression.

// inlined function
inline fun inlinedFunc(crossinline lmbd1: () -> Unit, lmbd2: () -> Unit) {
lmbd1()
lmbd2()
}

fun main() {
println
("Main function starts")
inlinedFunc(
{
println("Lambda expression 1")
return
},
// inlined function allow return
// statement in lambda expression
// so, does not give compile time error

{ println("Lambda expression 2") })

println("Main function ends")
}

Output:

Error:(6, 9) Kotlin: 'return' is not allowed here

Noinline :

In Kotlin, if we want only some of the lambdas passed to an inline function to be inlined, we can mark some of the function parameters with the noinline modifier.

Reified Type Parameters :

Sometimes we need to access the type of parameter passed during the call. We have to simply the pass of the parameter at the time function calling and we can retrieve the type of the parameter using a reified modifier.

inline fun <reified T> genericFunc() {
print(T::class)
}
fun main() {
genericFunc<String>()
}

Inline Properties :

Inlined function copy the code to the calling place, similarly inline keyword copy the inline properties accessor methods to calling place. The inline modifier can be used on accessors of properties that don’t have a backing field.

fun foo(i: Int): Int {
var a = i
return a
}

inline var flag: Boolean
get() = foo(10) == 10
set(flag) {
flag
}
fun main() {
println
(flag)
}

Output:

true

When not to use an inline function in Kotlin ?

If you have a simple function that doesn’t accept other functions as an argument, it does not make sense to inline them. IntelliJ will warn you.

In the next post, we talk more about Higher-order functions & Kotlin Inline classes in practical situations!

Happy Coding

--

--

Deepak Sikka

Senior Android Developer. Working on technology Like Java,Kotlin, JavaScript.Exploring Block Chain technology in simple words.