Bird
Raised Fist0
Kotlinprogramming~5 mins

Extensions for DSL building in Kotlin - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Extensions for DSL building
O(n^2)
Understanding Time Complexity

When we use extensions to build DSLs in Kotlin, we want to know how the program's running time changes as we add more elements.

We ask: How does the time to build or process the DSL grow when the input size grows?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


class Html {
    private val children = mutableListOf()
    fun body(block: Body.() -> Unit) {
        val body = Body()
        body.block()
        children.add(body.content)
    }
}

class Body {
    var content = ""
    fun p(text: String) { content += "

$text

" } } fun html(block: Html.() -> Unit): Html { val html = Html() html.block() return html }

This code builds a simple HTML DSL using extensions and lambdas to add paragraphs inside a body.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Adding paragraphs by appending strings inside the p function.
  • How many times: Once per paragraph added; each call appends to the content string but with increasing cost due to string immutability.
How Execution Grows With Input

Each paragraph added triggers a string append. Since strings are immutable, each append copies the current content (O(k) for the k-th append).

Input Size (n)Approx. Total Operations
1055
1005,050
1000500,500

Pattern observation: The total work grows quadratically with the number of paragraphs added.

Final Time Complexity

Time Complexity: O(n2)

This means the time to build the DSL grows quadratically with the number of elements added.

Common Mistake

[X] Wrong: "Using extensions for DSL building always makes the code run instantly regardless of input size."

[OK] Correct: Even with extensions, each added element requires work, so time grows with input size.

Interview Connect

Understanding how DSL building scales helps you explain how your code handles more data gracefully and shows you think about performance in real projects.

Self-Check

What if we changed the string concatenation in p to use a StringBuilder? How would the time complexity change?

Practice

(1/5)
1. What is the main purpose of using extensions in Kotlin for DSL building?
easy
A. To add new functions to existing classes without modifying their source code
B. To create new classes from scratch
C. To change the behavior of existing functions permanently
D. To restrict access to class members

Solution

  1. Step 1: Understand what extensions do

    Extensions allow adding new functions to existing classes without changing their original code.
  2. Step 2: Relate to DSL building

    This helps create readable DSLs by extending classes with custom functions.
  3. Final Answer:

    To add new functions to existing classes without modifying their source code -> Option A
  4. Quick Check:

    Extensions add functions without modifying classes [OK]
Hint: Extensions add functions without changing original classes [OK]
Common Mistakes:
  • Thinking extensions create new classes
  • Believing extensions permanently change existing functions
  • Confusing extensions with access control
2. Which of the following is the correct syntax to define an extension function greet for the String class in Kotlin?
easy
A. extension fun String greet() { println("Hello") }
B. fun greet(String) { println("Hello") }
C. fun String.greet() { println("Hello") }
D. fun greet() String { println("Hello") }

Solution

  1. Step 1: Recall extension function syntax

    Extension functions are declared with fun ClassName.functionName().
  2. Step 2: Match syntax to options

    fun String.greet() { println("Hello") } uses fun String.greet(), which is correct syntax.
  3. Final Answer:

    fun String.greet() { println("Hello") } -> Option C
  4. Quick Check:

    Extension syntax = fun ClassName.functionName() [OK]
Hint: Extension syntax: fun ClassName.functionName() [OK]
Common Mistakes:
  • Placing class name as parameter instead of receiver
  • Using 'extension' keyword which doesn't exist
  • Incorrect function return type placement
3. What will be the output of the following Kotlin code?
class Box(var content: String)

fun Box.describe() = "Box contains: $content"

fun main() {
    val box = Box("Apples")
    println(box.describe())
}
medium
A. Box contains: Apples
B. Box contains: content
C. Compilation error
D. Box@<memory_address>

Solution

  1. Step 1: Understand the extension function

    The extension function describe returns a string with the content property of Box.
  2. Step 2: Check the main function output

    Creating Box("Apples") and calling describe() prints "Box contains: Apples".
  3. Final Answer:

    Box contains: Apples -> Option A
  4. Quick Check:

    Extension uses property value correctly [OK]
Hint: Extension functions use class properties directly [OK]
Common Mistakes:
  • Expecting 'content' literal instead of property value
  • Confusing extension with overriding toString()
  • Thinking it prints memory address
4. Identify the error in this Kotlin code snippet that tries to build a simple DSL using extensions:
class Menu {
    val items = mutableListOf<String>()
}

fun Menu.addItem(name: String) {
    items.add(name)
}

fun buildMenu(block: Menu.() -> Unit): Menu {
    val menu = Menu()
    block(menu)
    return menu
}

fun main() {
    val menu = buildMenu {
        addItem("Home")
        addItem("About")
    }
    println(menu.items)
}
medium
A. The extension function addItem should be inside the Menu class
B. The block should be called with menu.block() instead of block(menu)
C. MutableList should be immutableList
D. No error, code runs correctly

Solution

  1. Step 1: Understand the block parameter type

    The block is a lambda with receiver: Menu.() -> Unit, so it should be called as menu.block().
  2. Step 2: Identify the call mistake

    The code calls block(menu), which treats block as a normal function, causing an error.
  3. Final Answer:

    The block should be called with menu.block() instead of block(menu) -> Option B
  4. Quick Check:

    Lambda with receiver called as receiver.lambda() [OK]
Hint: Call lambdas with receiver as receiver.lambda() [OK]
Common Mistakes:
  • Calling lambda with receiver as normal function
  • Placing extension function inside class unnecessarily
  • Confusing mutable and immutable lists
5. Given the following Kotlin DSL code, what is the output?
class Html {
    val children = mutableListOf<String>()
}

fun Html.body(block: Html.() -> Unit) {
    this.block()
}

fun Html.p(text: String) {
    children.add("

$text

") } fun html(block: Html.() -> Unit): Html { val html = Html() html.block() return html } fun main() { val page = html { body { p("Hello") p("World") } } println(page.children) }
hard
A. Compilation error due to missing body class
B. []
C. ["

Hello

World

"]
D. ["

Hello

", "

World

"]

Solution

  1. Step 1: Trace the DSL calls

    The html function creates an Html object and calls body extension, which calls p twice adding paragraphs to children.
  2. Step 2: Check the children list content

    Both p calls add strings "

    Hello

    " and "

    World

    " to the children list.
  3. Final Answer:

    ["

    Hello

    ", "

    World

    "]
    -> Option D
  4. Quick Check:

    Extensions build nested structure as list of strings [OK]
Hint: Extensions add elements to list step-by-step [OK]
Common Mistakes:
  • Expecting nested tags as single string
  • Assuming body creates separate object
  • Thinking code causes compilation error
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard