← Back to Kotlin Course | Chapter 4: Functions | Lesson 5 of 7

Local Functions

A local function is a helper recipe you define right inside another function, only for that function's own use.
Syntax
kotlin
fun outerFunction(param: Type) {
    fun localFunction(x: Type): ReturnType {
        return value   // can use param from outer
    }
    localFunction(value)
}

Declaring a Local Function

A function defined inside another function's body is a local function, usable only within that enclosing function, which keeps small helpers scoped tightly to where they are needed.

Example: Declaring a Local Function

markup
// Define the function `printReport` taking `total`
fun printReport(total: Int) {
    // Define the function `formatCurrency` taking `amount` and returning a String
    fun formatCurrency(amount: Int): String = "$$amount.00"

    // Print "Total: ${formatCurrency(total)}" to the console, with a trailing newline
    println("Total: ${formatCurrency(total)}")
}

// Entry point: execution of the program starts here
fun main() {
    printReport(150)
}

Accessing Enclosing Variables

A local function can read variables from the function it is nested inside directly, without needing them passed in as parameters.

Example: Accessing Enclosing Variables

markup
// Define the function `calculateDiscountedTotal` taking `prices`, `discountPercent`
fun calculateDiscountedTotal(prices: List<Int>, discountPercent: Int) {
    // Define the function `applyDiscount` taking `price` and returning an Int
    fun applyDiscount(price: Int): Int = price - (price * discountPercent / 100)

    // Declare a read-only variable `total`, set to `prices.sumBy { applyDiscount(it) }`
    val total = prices.sumBy { applyDiscount(it) }
    // Print "Discounted total: $total" to the console, with a trailing newline
    println("Discounted total: $total")
}

// Entry point: execution of the program starts here
fun main() {
    calculateDiscountedTotal(listOf(100, 200, 300), 10)
}

Breaking Up Long Functions

Extracting repeated or logically distinct steps into local functions keeps the outer function's body focused on the overall flow, while the details live in named, testable-in-isolation pieces.

Example: Breaking Up Long Functions

markup
// Define the function `processOrder` taking `itemCount`, `pricePerItem`
fun processOrder(itemCount: Int, pricePerItem: Int) {
    fun subtotal() = itemCount * pricePerItem
    fun tax(amount: Int) = amount / 10

    // Declare a read-only variable `sub`, set to `subtotal()`
    val sub = subtotal()
    // Print "Subtotal: $sub, Tax: ${tax(sub)}" to the console, with a trailing newline
    println("Subtotal: $sub, Tax: ${tax(sub)}")
}

// Entry point: execution of the program starts here
fun main() {
    processOrder(3, 50)
}

When to Avoid Local Functions

If a helper needs to be reused across several unrelated functions, it should be a regular top-level (or member) function instead of a local one, since local functions cannot be called from outside their enclosing function.

Example: When to Avoid Local Functions

markup
fun square(x: Int) = x * x

// Define the function `sumOfSquares` taking `a`, `b` and returning an Int
fun sumOfSquares(a: Int, b: Int): Int {
    // Return `square(a) + square(b)` from this function
    return square(a) + square(b)
}

// Entry point: execution of the program starts here
fun main() {
    // Print "Sum of squares: ${sumOfSquares(3, 4)}" to the console, with a trailing newline
    println("Sum of squares: ${sumOfSquares(3, 4)}")
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Making a helper a top-level function when it is only ever needed inside one other function, cluttering the file's namespace.
  2. Forgetting that a local function can directly access the variables of its enclosing function, leading to redundant parameters being passed in.
  3. Nesting local functions too deeply, hurting readability instead of helping it.
Chapter Summary
  • A local function is declared inside another function's body and is only visible there.
  • Local functions can directly read (and, if var, modify) variables from their enclosing function's scope.
  • They help break a long function into smaller named pieces without polluting the outer file scope.
  • Overusing deeply nested local functions can hurt readability just as much as one giant function.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.