With Kotlin you can do much more with functions as compared to JAVA. Lets explore some of the features related to functions offered by Kotlin.

If you are completely new to functions in Kotlin, then please read this: Getting Started with Kotlin – Tutorial 4 – Functions

Local Functions

In Kotlin, you can define function inside of functions. These are called local functions. Here is an example:

Local Functions //Local Functions in Kotlin fun outerFunction(param: String) { fun localFunction(innerParam: String) { println(innerParam) println(param) } } 1 2 3 4 5 6 7 8 9 //Local Functions in Kotlin fun outerFunction ( param : String ) { fun localFunction ( innerParam : String ) { println ( innerParam ) println ( param ) } }

The local functions has complete access to the variables defined in the enclosing functions. You can define as many local functions as you want.

Infix Functions

If your function is an extension function and takes only one argument then kotlin provides a more pragmatic way to call the function using the infix keyword.

Lets say I have an extension function on ‘Int’ that takes another ‘Int’ as an argument and tell whether it is greater or not.

Without Infix Notation fun Int.isGreater(value: Int):Boolean { return this > value } 1 2 3 fun Int . isGreater ( value : Int ) : Boolean { return this > value }

The function call will look something like this.

Function Call 1.isGreater(12) 1 1.isGreater ( 12 )

What we have to do is just add the infix keyword before the function.

Infix Notation infix fun Int.isGreater(value: Int):Boolean { return this > value } 1 2 3 infix fun Int . isGreater ( value : Int ) : Boolean { return this > value }

By doing this we can call the function more pragmatically.

Infix Function Call 1 isGreater 12 1 1 isGreater 12

A very small feature, but one that makes the code look a whole lot better. Nice!

Returns and Local Returns

Suppose you have a function inside which you have are calling another function that takes in a lambda function. Lets take an example, a function named outerFunction contains an IntRange from 1 to 100, and using the forEach function on the range object we are looping over the range. (forEach function takes in a lambda)

Return and Local Return fun outerFunction() { val numbers = 1..100 numbers.forEach { ... } println("Hello") } 1 2 3 4 5 6 7 8 fun outerFunction ( ) { val numbers = 1..100 numbers . forEach { . . . } println ( "Hello" ) }

Now inside the forEach I want to exit the loop when the value reaches 25. You might think the solution might be putting a return keyword at the end of forEach loop,

Wrong solution //Returns and local returns fun outerFunction() { val numbers = 1..100 numbers.forEach { if (it == 25) { return } } println("Hello") } 1 2 3 4 5 6 7 8 9 10 11 //Returns and local returns fun outerFunction ( ) { val numbers = 1..100 numbers . forEach { if ( it == 25 ) { return } } println ( "Hello" ) }

Well, this is not the solution, “Hello” will not be printed because adding a return statement will not return the control from the forEach but it will return the control from the outerFunction itself. You might have faced the same issue in other programming languages as well. Kotlin has a fix for it, called labels. The basic idea is that you will explicitly tell kotlin from which scope to return the control flow. Lets see how we will return from forEach.

Right solution using labels //Returns and local returns fun outerFunction() { val numbers = 1..100 numbers.forEach { if (it == 25) { return@forEach } } println("Hello") } 1 2 3 4 5 6 7 8 9 10 11 //Returns and local returns fun outerFunction ( ) { val numbers = 1..100 numbers . forEach { if ( it == 25 ) { return @ forEach } } println ( "Hello" ) }

After the return keyword we specify the name from which we want to return. The name ‘forEach’ is available by default because we are inside of forEach loop. Now suppose there is a forEach inside a forEach, the complier will not know which one you are referring to. In this case we use custom labels, we will explicitly give a label name to the scope blocks.

Custom Labels //Returns and local returns fun outerFunction() { val numbers = 1..100 numbers.forEach outerForEach@{ numbers.forEach innerForEach@{ if (it % 5 == 0) { return@innerForEach } } } println("Hello") } 1 2 3 4 5 6 7 8 9 10 11 12 13 //Returns and local returns fun outerFunction ( ) { val numbers = 1..100 numbers . forEach outerForEach @ { numbers . forEach innerForEach @ { if ( it % 5 == 0 ) { return @ innerForEach } } } println ( "Hello" ) }

In the highlighted part above you can see the syntax for providing a custom label, the name of label followed by @.

These are some of the many powerful features provided by Kotlin. I hope you have learned something new or have brushed up on some of the concepts that you already knew.