Lambda with receiver concept in Kotlin - Time & Space Complexity
Let's see how the time needed to run a lambda with receiver changes as the input grows.
We want to know how the number of operations grows when using this Kotlin feature.
Analyze the time complexity of the following code snippet.
fun buildStringExample(n: Int): String = buildString {
repeat(n) {
append("*")
}
}
This code uses a lambda with receiver to build a string by adding n stars.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The repeat loop that calls append n times.
- How many times: Exactly n times, once per loop iteration.
Each time we add one more star, the loop runs one more time, so work grows steadily.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 appends |
| 100 | 100 appends |
| 1000 | 1000 appends |
Pattern observation: The work grows directly in proportion to n.
Time Complexity: O(n)
This means the time to build the string grows in a straight line as n increases.
[X] Wrong: "Using a lambda with receiver makes the code run instantly regardless of n."
[OK] Correct: The lambda with receiver just changes how we write code, but the loop inside still runs n times, so time grows with n.
Understanding how lambdas with receivers work helps you write clear Kotlin code and also think about how your code's speed changes with input size.
"What if we replaced repeat(n) with a nested loop inside the lambda? How would the time complexity change?"
Practice
lambda with receiver in Kotlin?Solution
Step 1: Understand lambda with receiver purpose
A lambda with receiver lets you write code blocks that behave as if they belong to an object, so you can call its methods directly.Step 2: Identify the benefit
This means you don't have to repeat the object name inside the lambda, making code cleaner and easier to read.Final Answer:
It allows you to call methods on an object without repeating the object name inside the lambda. -> Option DQuick Check:
Lambda with receiver = cleaner calls [OK]
- Thinking it creates new objects automatically
- Assuming it restricts return types
- Believing it blocks outer variables
StringBuilder in Kotlin?Solution
Step 1: Recall lambda with receiver syntax
A lambda with receiver is declared by specifying the receiver type followed by a dot and then the function type, likeStringBuilder.() -> Unit.Step 2: Match syntax with options
val lambda: StringBuilder.() -> Unit = { append("Hello") } matches this syntax and usesappend("Hello")inside the lambda, which is valid forStringBuilder.Final Answer:
val lambda: StringBuilder.() -> Unit = { append("Hello") } -> Option CQuick Check:
Receiver syntax = Type.() -> ReturnType [OK]
- Confusing parameter lambdas with receiver lambdas
- Missing the dot after the receiver type
- Using arrow without parentheses
val buildString: StringBuilder.() -> Unit = {
append("Hi")
append(", ")
append("there!")
}
val result = StringBuilder().apply(buildString).toString()
println(result)Solution
Step 1: Understand the lambda with receiver usage
The lambdabuildStringis aStringBuilderreceiver lambda that appends "Hi", ", ", and "there!" to theStringBuilder.Step 2: Apply lambda and convert to string
Theapplyfunction runs the lambda on a newStringBuilderinstance, thentoString()converts it to the string "Hi, there!".Final Answer:
Hi, there! -> Option BQuick Check:
apply + receiver lambda = built string [OK]
- Expecting default toString output of StringBuilder
- Missing commas in output
- Thinking lambda returns string directly
val printLength: String.() -> Unit = {
println(length())
}
"Hello".printLength()Solution
Step 1: Check usage of length inside lambda
In Kotlin,lengthis a property ofString, not a function, so callinglength()causes an error.Step 2: Verify other parts
The lambda correctly usesStringas receiver and returns Unit, and callingprintLengthwithout parentheses is valid syntax.Final Answer:
Cannot call length() as a function; length is a property. -> Option AQuick Check:
Properties accessed without () [OK]
- Using parentheses with properties
- Thinking receiver type can't be String
- Forgetting lambda return type can be Unit
buildHtml that uses a lambda with receiver to build an HTML string with nested tags. Which approach correctly uses lambda with receiver to achieve this?fun buildHtml(block: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.block()
return sb.toString()
}
val html = buildHtml {
append("")
append("")
append("Hello")
append("")
append("")
}
println(html)Solution
Step 1: Analyze the function signature and call
The functionbuildHtmltakes a lambda with receiverStringBuilder.() -> Unitand calls it onsbusingsb.block(), which is correct syntax.Step 2: Check the lambda body and return
The lambda appends HTML tags toStringBuilder, and the function returns the built string withsb.toString(), which is the expected behavior.Final Answer:
This code correctly uses a lambda with receiver to build the HTML string. -> Option AQuick Check:
Lambda with receiver called on object = correct [OK]
- Confusing lambda with receiver and lambda with parameter
- Forgetting to call lambda on the object
- Expecting lambda to return string directly
Ready to prove it?
Pass the test and this pattern moves unknown
