Passing lambdas to functions in Kotlin - Time & Space Complexity
When we pass lambdas (small blocks of code) to functions, it's important to see how this affects the time the program takes to run.
We want to know how the number of times the lambda runs changes as the input grows.
Analyze the time complexity of the following code snippet.
fun applyToList(numbers: List, action: (Int) -> Unit) {
for (number in numbers) {
action(number)
}
}
fun main() {
val nums = listOf(1, 2, 3, 4, 5)
applyToList(nums) { println(it) }
}
This code runs a given lambda on each item in a list, printing each number.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop that goes through each item in the list.
- How many times: Once for every item in the list.
As the list gets bigger, the lambda runs more times, once per item.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 lambda calls |
| 100 | 100 lambda calls |
| 1000 | 1000 lambda calls |
Pattern observation: The number of operations grows directly with the size of the list.
Time Complexity: O(n)
This means the time to run grows in a straight line with the number of items.
[X] Wrong: "Passing a lambda makes the code run slower in a way that multiplies the work."
[OK] Correct: The lambda runs once per item, just like any code inside the loop. It doesn't add hidden extra loops or repeats.
Understanding how lambdas affect time helps you explain your code clearly and shows you know how to reason about performance in real projects.
"What if the lambda itself contains a loop over the list? How would the time complexity change?"
Practice
Solution
Step 1: Understand what a lambda is
A lambda is a small piece of code that you can write inline and pass around like a value.Step 2: Recognize its use in functions
Functions can accept lambdas to customize behavior without changing the function code.Final Answer:
A small block of code that can be passed and executed inside the function -> Option AQuick Check:
Lambda = small code block passed to function [OK]
- Thinking lambda is a variable type
- Confusing lambda with loops
- Believing lambda is a keyword for classes
Solution
Step 1: Check function parameter type
The function expects a lambda with no parameters and no return value: () -> Unit.Step 2: Check how lambda is called and passed
Inside the function, calling action() executes the lambda. Passing greet { println("Hi") } is correct syntax.Final Answer:
fun greet(action: () -> Unit) { action() } greet { println("Hi") } -> Option BQuick Check:
Correct lambda syntax = fun greet(action: () -> Unit) { action() } greet { println("Hi") } [OK]
- Wrong lambda type syntax
- Forgetting to call lambda with ()
- Passing lambda as function argument incorrectly
fun operate(x: Int, action: (Int) -> Int): Int {
return action(x)
}
fun main() {
val result = operate(5) { it * 2 }
println(result)
}Solution
Step 1: Understand the operate function
It takes an integer and a lambda that doubles the integer (it * 2).Step 2: Calculate the result
Passing 5 to the lambda doubles it to 10, which is returned and printed.Final Answer:
10 -> Option CQuick Check:
5 * 2 = 10 [OK]
- Confusing input and output values
- Forgetting lambda parameter 'it'
- Assuming no return from lambda
fun applyOperation(x: Int, op: (Int) -> Int) {
op(x)
}
fun main() {
applyOperation(3) { println(it * 3) }
}Solution
Step 1: Check function signature and lambda
applyOperation expects a lambda returning Int, but the lambda only prints and returns Unit.Step 2: Understand mismatch consequences
Because the lambda returns Unit, but function expects Int, this causes a type mismatch error.Final Answer:
The lambda passed does not return a value but function expects Int return -> Option DQuick Check:
Lambda return type mismatch = The lambda passed does not return a value but function expects Int return [OK]
- Ignoring return type mismatch
- Thinking println returns Int
- Assuming no return needed for lambdas
filterAndTransform that takes a list of integers and two lambdas: one to filter the list and one to transform each filtered item. Which of these function signatures correctly allows passing both lambdas?Solution
Step 1: Identify correct lambda types for filtering and transforming
Filtering needs a lambda that takes Int and returns Boolean; transforming needs a lambda that takes Int and returns Int.Step 2: Match function signature with these lambda types
fun filterAndTransform(list: List<Int>, filter: (Int) -> Boolean, transform: (Int) -> Int): List<Int> matches these types correctly; others have wrong parameter or return types.Final Answer:
fun filterAndTransform(list: List<Int>, filter: (Int) -> Boolean, transform: (Int) -> Int): List<Int> -> Option AQuick Check:
Filter returns Boolean, transform returns Int [OK]
- Using wrong lambda parameter or return types
- Confusing filter and transform lambda roles
- Using lambdas with no parameters
Ready to prove it?
Pass the test and this pattern moves unknown
