Open In App

Local Functions in Kotlin

Last Updated : 21 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

One of the simplest and most important ideas in programming is to break a large problem into smaller pieces. These small, reusable pieces of code are called functions. Functions help us write clearer, more manageable programs and also follow an important principle called DRY (Don’t Repeat Yourself). DRY is so important because when we write the same code multiple times, there’s more chance of making mistakes or bugs. The DRY principle teaches us to avoid this by reusing code instead of duplicating it. When we apply this idea thoroughly, our programs will be made up of many small functions, where each function does only one specific task. This is similar to the Unix philosophy, where every small tool or command is designed to do just one thing well. In many languages, like Java, we often break large functions into smaller ones, either inside the same class or by using helper classes. Kotlin lets us go even further by allowing functions to be declared inside other functions. These are called local functions (also called nested functions).

Local Function

A local function is simply a function declared inside another function. This inner function is hidden from the outside world, it can only be used inside the outer function. This is very useful when we want to create helper functions that are only needed in one specific place and don’t need to be exposed to the rest of the program.

Example:

Kotlin
fun printArea(length: Int, width: Int) {
    fun calculateArea(): Int {
        return length * width
    }
    println("The area is ${calculateArea()}")
}

Here, calculateArea() is inside printArea(). It can directly access the parameters length and width of the outer function without needing them to be passed again as arguments.


Advantages of Local Functions

Local functions have some great advantages:

  1. Encapsulation: The inner function can’t be accessed from outside, it's completely hidden.
  2. Readability: The local function stays close to where it's used. This makes the code easier to follow.
  3. Access to Outer Scope: Local functions can automatically use variables and parameters from the outer function, no need to pass everything again.

Example

Let’s see a real example - FizzBuzz.

Problem: Print numbers from start to end. If a number is divisible by 3, print “Fizz”. If divisible by 5, print “Buzz”. If divisible by both, print “FizzBuzz”. Otherwise, print the number itself.

Solution 1 - Simple solution:

Kotlin
fun fizzBuzz(start: Int, end: Int) {
    for (k in start..end) {
        if (k % 3 == 0 && k % 5 == 0) println("FizzBuzz")
        else if (k % 3 == 0) println("Fizz")
        else if (k % 5 == 0) println("Buzz")
        else println(k)
    }
}

The problem here is we're repeating modulo checks multiple times. What if we accidentally type the wrong divisor. In bigger problems, this can easily happen.


Solution 2 - Using Local Functions to Avoid Repetition:

Kotlin
fun fizzBuzz(start: Int, end: Int) {
    fun isFizz(k: Int) = k % 3 == 0
    fun isBuzz(k: Int) = k % 5 == 0

    for (k in start..end) {
        if (isFizz(k) && isBuzz(k)) println("FizzBuzz")
        else if (isFizz(k)) println("Fizz")
        else if (isBuzz(k)) println("Buzz")
        else println(k)
    }
}

Now the modulo logic is written only once in isFizz and isBuzz. It is cleaner and safer.


Solution 3 - Using Outer Variables in Local Functions:

We can go further by defining local functions inside the loop and letting them access the loop variable directly.

Kotlin
fun fizzBuzz(start: Int, end: Int) {
    for (k in start..end) {
        fun isFizz() = k % 3 == 0
        fun isBuzz() = k % 5 == 0

        println(
            when {
                isFizz() && isBuzz() -> "FizzBuzz"
                isFizz() -> "Fizz"
                isBuzz() -> "Buzz"
                else -> k
            }
        )
    }
}

Notice that we no longer need to pass k as a parameter, the local functions see it directly. The result is code that is short, clear, and avoids duplication.


Next Article

Similar Reads