Local functions (nested functions) in Kotlin - Time & Space Complexity
We want to see how the time it takes to run code with local functions changes as the input grows.
How does nesting a function inside another affect the total work done?
Analyze the time complexity of the following code snippet.
fun printNumbers(n: Int) {
fun helper(i: Int) {
if (i > n) return
println(i)
helper(i + 1)
}
helper(1)
}
This code prints numbers from 1 to n using a local (nested) recursive function.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The recursive call to
helperthat prints each number. - How many times: It runs once for each number from 1 up to n, so n times.
Each time we increase n, the function does one more print and recursive call.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 prints and calls |
| 100 | About 100 prints and calls |
| 1000 | About 1000 prints and calls |
Pattern observation: The work grows directly with n, adding one step per number.
Time Complexity: O(n)
This means the time to finish grows in a straight line with the input size.
[X] Wrong: "Because the function is nested, it runs faster or slower than a normal function."
[OK] Correct: Nesting a function inside another does not change how many times it runs; only the number of calls matters.
Understanding how local functions behave helps you explain recursion and function structure clearly, a useful skill in many coding discussions.
"What if the local function called itself twice each time instead of once? How would the time complexity change?"
Practice
Solution
Step 1: Understand function placement
Local functions are defined inside other functions, not at the top level or in classes.Step 2: Identify the correct definition
A function defined inside another function correctly states that a local function is inside another function, which matches Kotlin's definition.Final Answer:
A function defined inside another function -> Option BQuick Check:
Local function = function inside function [OK]
- Thinking local functions are top-level
- Confusing local functions with anonymous functions
- Assuming local functions must be public
Solution
Step 1: Recall Kotlin function syntax
Kotlin uses the keyword 'fun' to declare functions, including local ones.Step 2: Check each option
fun outer() { fun inner() { println("Hi") } } uses 'fun' correctly for both outer and inner functions. Others use invalid keywords or wrong order.Final Answer:
fun outer() { fun inner() { println("Hi") } } -> Option AQuick Check:
Local function syntax uses 'fun' keyword [OK]
- Using 'def' or 'function' instead of 'fun'
- Placing 'fun' after the function call
- Missing braces for function body
fun greet() {
val prefix = "Hello"
fun sayName(name: String) {
println("$prefix, $name!")
}
sayName("Alice")
}
fun main() {
greet()
}Solution
Step 1: Understand variable scope in local functions
The local function 'sayName' can access 'prefix' from the outer function 'greet'.Step 2: Trace the output of sayName("Alice")
It prints "Hello, Alice!" exactly as formatted with the comma and exclamation mark.Final Answer:
Hello, Alice! -> Option AQuick Check:
Local function accesses outer variable = Hello, Alice! [OK]
- Assuming outer variables are inaccessible
- Missing punctuation in output
- Thinking code produces error
fun calculate() {
fun add(a: Int, b: Int): Int {
return a + b
}
}
fun main() {
println(add(3, 4))
}Solution
Step 1: Understand local function visibility
The function 'add' is local inside 'calculate' and cannot be accessed outside it.Step 2: Check where 'add' is called
'add(3, 4)' is called in 'main', outside 'calculate', causing an error.Final Answer:
Cannot call local function 'add' from outside 'calculate' -> Option CQuick Check:
Local functions are private to outer function [OK]
- Trying to call local function from outside
- Confusing local and top-level functions
- Ignoring function scope rules
processNumbers that takes a list of integers and returns the sum of their squares. You decide to use a local function square inside it. Which of the following implementations correctly uses a local function to achieve this?Solution
Step 1: Understand local function usage and Kotlin collection functions
Local function 'square' should be declared once inside 'processNumbers'. Using Kotlin's 'sumOf' is concise and correct.Step 2: Analyze each option
fun processNumbers(nums: List<Int>): Int { fun square(x: Int) = x * x return nums.sumOf { square(it) } } correctly declares the local function once and uses it with sumOf { square(it) }.
fun processNumbers(nums: List<Int>): Int { var sum = 0 for (n in nums) { fun square(x: Int) = x * x sum += square } return sum } declares 'square' inside the loop but calls it without argument square(n), compile error.
fun processNumbers(nums: List<Int>): Int { fun square(x: Int) = x * x return nums.map square(it).sum() } has syntax error: nums.map square(it).sum() missing lambda braces {}.
fun processNumbers(nums: List<Int>): Int { fun square(x: Int) = x * x var sum = 0 for (n in nums) { sum += n } return sum } defines 'square' but uses sum += n, computes sum of numbers not squares.Final Answer:
fun processNumbers(nums: List<Int>): Int { fun square(x: Int) = x * x return nums.sumOf { square(it) } } -> Option DQuick Check:
Local function + sumOf = fun processNumbers(nums: List<Int>): Int { fun square(x: Int) = x * x return nums.sumOf { square(it) } } [OK]
- Calling local function without required arguments
- Syntax error: missing braces in lambda expression
- Defining local function but forgetting to use it
Ready to prove it?
Pass the test and this pattern moves unknown
