Bird
Raised Fist0
Kotlinprogramming~10 mins

Extensions for DSL building in Kotlin - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Extensions for DSL building
Define Extension Function
↓
Call Extension in DSL
↓
Build DSL Structure
↓
Use Lambda with Receiver
↓
Configure Object Inside Lambda
↓
Return Configured Object
This flow shows how Kotlin extension functions help build DSLs by adding functions to existing types, using lambdas with receivers to configure objects inside a clean syntax.
Execution Sample
Kotlin
class Robot(var name: String) {
    var speed = 0
}

fun Robot.move(block: Robot.() -> Unit) {
    this.block()
}

fun main() {
    val r = Robot("R2D2")
    r.move { speed = 10 }
    println(r.speed)
}
This code defines an extension function 'move' for Robot that takes a lambda to configure the robot's speed, then prints the speed.
Execution Table
StepActionEvaluationResult
1Create Robot instance r with name 'R2D2'Robot(name='R2D2', speed=0)r = Robot(name='R2D2', speed=0)
2Call extension function r.move with lambda { speed = 10 }Invoke move extensionInside move: this = r
3Execute lambda: speed = 10Set r.speed to 10r.speed = 10
4Exit move functionReturn Unitr.speed remains 10
5Print r.speedOutput value10
💡 Program ends after printing the robot's speed, which is 10
Variable Tracker
VariableStartAfter Step 1After Step 3Final
r.nameundefinedR2D2R2D2R2D2
r.speed001010
Key Moments - 2 Insights
Why can we call 'speed = 10' inside the lambda without specifying 'r.speed'?
Inside the lambda passed to the extension function, 'this' refers to the Robot instance 'r', so we can access its properties directly, as shown in execution_table step 3.
What does the extension function 'move' add to the Robot class?
It adds a new function that takes a lambda with receiver, allowing configuration of Robot instances in a DSL style, demonstrated in execution_table step 2.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of r.speed after step 3?
A10
B0
Cundefined
DError
💡 Hint
Check the 'Result' column in row for step 3 in the execution_table.
At which step is the lambda passed to 'move' executed?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look at the 'Action' and 'Evaluation' columns in execution_table rows to find when 'speed = 10' is set.
If we remove 'this.block()' from the 'move' extension, what happens?
ACompilation error
BThe lambda runs automatically, speed becomes 10
CThe lambda is never executed, speed stays 0
DRobot instance is not created
💡 Hint
Refer to execution_table step 2 and 3 where the lambda is explicitly called.
Concept Snapshot
Kotlin extensions let you add functions to existing classes.
Use lambdas with receiver (e.g., Robot.() -> Unit) to build DSLs.
Inside the lambda, 'this' is the receiver object.
Call the lambda inside the extension to apply configuration.
This creates clean, readable DSL-style code.
Full Transcript
This example shows how Kotlin extension functions help build DSLs by adding new functions to existing classes. We define a Robot class with a speed property. Then we add an extension function 'move' that takes a lambda with receiver to configure the Robot instance. When we call r.move { speed = 10 }, the lambda runs with 'this' as the Robot, so we set speed directly. The execution table traces creating the Robot, calling move, running the lambda, and printing the speed. The variable tracker shows how r.speed changes from 0 to 10. Key moments clarify why we can access speed directly inside the lambda and what the extension function adds. The quiz tests understanding of variable values and lambda execution. The snapshot summarizes how extensions and lambdas with receiver enable DSL building in Kotlin.

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