Returning functions from functions in Kotlin - Time & Space Complexity
When a function returns another function, we want to know how the time it takes grows as inputs change.
We ask: How does calling the returned function affect overall work done?
Analyze the time complexity of the following code snippet.
fun multiplier(factor: Int): (Int) -> Int {
return { number: Int -> number * factor }
}
fun main() {
val timesTwo = multiplier(2)
println(timesTwo(10))
}
This code returns a function that multiplies a number by a given factor.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Multiplying two numbers inside the returned function.
- How many times: Each time the returned function is called, once per call.
The multiplication inside the returned function takes the same time no matter the input size.
| Number of Calls (n) | Approx. Operations |
|---|---|
| 10 | 10 multiplications |
| 100 | 100 multiplications |
| 1000 | 1000 multiplications |
Pattern observation: The work grows linearly with how many times you call the returned function.
Time Complexity: O(n)
This means the total time grows directly with the number of times you call the returned function.
[X] Wrong: "Returning a function means the original function does a lot of work upfront."
[OK] Correct: The original function just creates and returns a small function quickly; the real work happens when you call the returned function.
Understanding how returned functions work helps you explain how code runs step-by-step, a skill useful in many coding challenges.
"What if the returned function did a loop inside it? How would the time complexity change?"
Practice
Solution
Step 1: Understand function return types
In Kotlin, a function can return any type, including another function type.Step 2: Interpret returning a function
Returning a function means the outer function gives back a function that can be stored or called later.Final Answer:
The outer function produces a function as its result that can be called later. -> Option CQuick Check:
Returning a function means output is a callable function [OK]
- Thinking only primitive types can be returned
- Assuming returned function must be called immediately
- Believing returned functions cannot have parameters
Solution
Step 1: Check function return type syntax
In Kotlin, a function returning another function uses syntax like: fun name(): (ParamType) -> ReturnTypeStep 2: Verify the return statement
The function returns a lambda matching (Int) -> String, e.g., { i -> i.toString() }Final Answer:
fun outer(): (Int) -> String { return { i -> i.toString() } } -> Option BQuick Check:
Correct function type syntax = fun outer(): (Int) -> String { return { i -> i.toString() } } [OK]
- Using arrow -> incorrectly in return type
- Mixing return type syntax with function body
- Omitting parentheses around function type
fun makeMultiplier(x: Int): (Int) -> Int {
return { y -> x * y }
}
fun main() {
val multiplyBy3 = makeMultiplier(3)
println(multiplyBy3(5))
}Solution
Step 1: Understand makeMultiplier function
makeMultiplier returns a function that multiplies its input by x (captured from outer function).Step 2: Trace main function calls
multiplyBy3 is a function multiplying by 3; multiplyBy3(5) = 3 * 5 = 15.Final Answer:
15 -> Option DQuick Check:
3 * 5 = 15 [OK]
- Confusing parameter names
- Forgetting the closure captures x
- Expecting immediate multiplication without calling returned function
fun outer(): (Int) -> Int {
val inner = { x: Int -> x * 2 }
return inner()
}Solution
Step 1: Analyze return statement
inner is a lambda function; inner() calls it and returns Int, not a function.Step 2: Correct return value
To return the function itself, return inner without parentheses.Final Answer:
Calling inner() instead of returning the function itself -> Option AQuick Check:
Return function, not function call [OK]
- Returning function call instead of function
- Omitting function return type
- Misunderstanding lambda syntax
fun createCounter(start: Int): () -> Int {
var count = start
return {
count += 1
count
}
}
fun main() {
val counter = createCounter(10)
println(counter())
println(counter())
}Solution
Step 1: Understand closure capturing variable
The returned lambda captures 'count' variable and increments it each call.Step 2: Trace calls to counter()
First call: count = 10 + 1 = 11; prints 11. Second call: count = 11 + 1 = 12; prints 12.Final Answer:
11 12 -> Option AQuick Check:
Closure increments count on each call [OK]
- Assuming count resets each call
- Confusing initial value with first output
- Expecting compilation error due to var usage
Ready to prove it?
Pass the test and this pattern moves unknown
