Bird
Raised Fist0
Kotlinprogramming~20 mins

Building blocks of type-safe builders in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Type-Safe Builder Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Kotlin type-safe builder code?
Consider this Kotlin code using a type-safe builder pattern. What will it print?
Kotlin
class Html {
    private val children = mutableListOf<String>()
    fun body(init: Body.() -> Unit) {
        val body = Body()
        body.init()
        children.add(body.render())
    }
    fun render() = "<html>" + children.joinToString() + "</html>"
}

class Body {
    private val texts = mutableListOf<String>()
    fun p(text: String) {
        texts.add("<p>$text</p>")
    }
    fun render() = texts.joinToString("")
}

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

fun main() {
    val page = html {
        body {
            p("Hello")
            p("World")
        }
    }
    println(page.render())
}
A<html><p>Hello</p><p>World</p></html>
B<html><p>HelloWorld</p></html>
C<html><body><p>Hello</p><p>World</p></body></html>
D<html><body>HelloWorld</body></html>
Attempts:
2 left
💡 Hint
Look at how the Body class renders its paragraphs and how Html collects children.
🧠 Conceptual
intermediate
1:30remaining
Which Kotlin feature enables type-safe builders to restrict DSL usage?
In Kotlin type-safe builders, which language feature helps restrict the scope of DSL functions to prevent misuse?
AThe lateinit modifier
BThe companion object
CThe inline keyword
DThe @DslMarker annotation
Attempts:
2 left
💡 Hint
This feature marks DSL receiver classes to avoid mixing scopes.
🔧 Debug
advanced
2:00remaining
Why does this Kotlin type-safe builder code cause a compilation error?
Examine the code below. Why does it fail to compile?
Kotlin
class Container {
    fun addItem(item: String) {
        println("Added: $item")
    }
}

fun container(init: Container.() -> Unit): Container {
    val c = Container()
    c.init()
    return c
}

fun main() {
    container {
        addItem("First")
        addItem(123) // Error here
    }
}
ABecause Container class lacks a constructor
BBecause container function is missing return type
CBecause addItem expects a String but 123 is an Int
DBecause init lambda is not marked inline
Attempts:
2 left
💡 Hint
Check the parameter type of addItem and the argument passed.
📝 Syntax
advanced
1:30remaining
Which option correctly defines a Kotlin type-safe builder function with receiver?
Select the correct syntax for a Kotlin function that takes a lambda with receiver to build a DSL.
Afun build(init: Builder.() -> Unit): Unit { val b = Builder(); init(b) }
Bfun build(init: Builder.() -> Unit): Builder { val b = Builder(); b.init(); return b }
Cfun build(init: Builder -> Unit): Builder { val b = Builder(); init(b); return b }
Dfun build(init: (Builder) -> Unit): Builder { val b = Builder(); init(b); return b }
Attempts:
2 left
💡 Hint
Look for the correct lambda with receiver syntax and return type.
🚀 Application
expert
1:30remaining
How many items are in the resulting list after this Kotlin type-safe builder runs?
Given this Kotlin code using a type-safe builder, how many items does the list contain after execution?
Kotlin
class ListBuilder {
    private val items = mutableListOf<String>()
    fun item(value: String) {
        items.add(value)
    }
    fun build() = items
}

fun list(init: ListBuilder.() -> Unit): List<String> {
    val builder = ListBuilder()
    builder.init()
    return builder.build()
}

fun main() {
    val result = list {
        item("A")
        item("B")
        item("C")
    }
    println(result.size)
}
A3
B0
C1
DCompilation error
Attempts:
2 left
💡 Hint
Count how many times item() is called inside the builder.

Practice

(1/5)
1. What is the main purpose of type-safe builders in Kotlin?
easy
A. To create complex objects step-by-step with safety and clarity
B. To write faster loops for collections
C. To handle exceptions automatically
D. To convert data types implicitly

Solution

  1. Step 1: Understand the concept of type-safe builders

    Type-safe builders allow building complex objects in a structured and safe way using Kotlin's DSL features.
  2. Step 2: Identify the main purpose

    The main goal is to create objects step-by-step with clear rules, avoiding errors and improving readability.
  3. Final Answer:

    To create complex objects step-by-step with safety and clarity -> Option A
  4. Quick Check:

    Type-safe builders = safe, clear object creation [OK]
Hint: Type-safe builders help build objects safely step-by-step [OK]
Common Mistakes:
  • Confusing builders with loops or exception handling
  • Thinking they convert data types automatically
2. Which Kotlin syntax correctly defines a type-safe builder function named html that takes a lambda with receiver?
easy
A. fun html(block: (Html) -> Unit) { /*...*/ }
B. fun html(block: () -> Html) { /*...*/ }
C. fun html(block: Html.() -> Unit) { /*...*/ }
D. fun html(block: () -> Unit) { /*...*/ }

Solution

  1. Step 1: Identify lambda with receiver syntax

    Type-safe builders use lambdas with receiver, which have the form ReceiverType.() -> ReturnType.
  2. Step 2: Match the correct function signature

    The function should accept a lambda with receiver Html and return Unit, so Html.() -> Unit is correct.
  3. Final Answer:

    fun html(block: Html.() -> Unit) { /*...*/ } -> Option C
  4. Quick Check:

    Lambda with receiver = Html.() -> Unit [OK]
Hint: Look for lambda with receiver syntax ReceiverType.() -> Unit [OK]
Common Mistakes:
  • Using regular lambda (Html) -> Unit instead of lambda with receiver
  • Omitting the receiver type in the lambda
  • Returning Html instead of Unit
3. Given the following Kotlin code, what is the output?
class Html {
    val children = mutableListOf<String>()
    fun body(block: Body.() -> Unit) {
        val body = Body()
        body.block()
        children.addAll(body.contents)
    }
    override fun toString() = children.joinToString(", ")
}

class Body {
    val contents = mutableListOf<String>()
    fun p(text: String) {
        contents.add("

$text

") } } fun html(block: Html.() -> Unit): Html { val html = Html() html.block() return html } fun main() { val result = html { body { p("Hello") p("World") } } println(result) }
medium
A. Hello, World
B. <p>Hello</p>, <p>World</p>
C. <body><p>Hello</p><p>World</p></body>
D. Compilation error

Solution

  1. Step 1: Understand the builder structure

    The html function creates an Html object, calls body which creates a Body object, then calls p twice adding <p>Hello</p> and <p>World</p> to Body's contents.
  2. Step 2: Check how children are collected and printed

    The Html object's children list gets Body's contents added, then toString() joins them with ", ". So output is "<p>Hello</p>, <p>World</p>".
  3. Final Answer:

    <p>Hello</p>, <p>World</p> -> Option B
  4. Quick Check:

    Children list joined = <p>Hello</p>, <p>World</p> [OK]
Hint: Look for toString join of children list for output [OK]
Common Mistakes:
  • Assuming HTML tags are printed as is without escaping
  • Expecting full HTML tags like <body> in output
  • Thinking code causes compilation error
4. What is the error in this Kotlin builder code snippet?
class Html {
    fun body(block: Body.() -> Unit) {
        val body = Body()
        block()
    }
}

class Body {
    fun p(text: String) { /*...*/ }
}

fun main() {
    val html = Html()
    html.body {
        p("Hello")
    }
}
medium
A. The lambda is called without receiver, so 'p' is unresolved
B. Body class is missing a constructor
C. Html class should inherit from Body
D. The 'body' function should return a value

Solution

  1. Step 1: Check how the lambda is called inside body()

    The lambda block is called as block() without receiver, so inside the lambda 'p' is not recognized.
  2. Step 2: Identify correct lambda invocation

    It should be called as body.block() to set the receiver to the Body instance, allowing 'p' to be resolved.
  3. Final Answer:

    The lambda is called without receiver, so 'p' is unresolved -> Option A
  4. Quick Check:

    Lambda call without receiver = unresolved 'p' [OK]
Hint: Call lambda with receiver: use receiver.lambda() syntax [OK]
Common Mistakes:
  • Calling lambda without receiver inside builder
  • Assuming inheritance fixes builder scope
  • Expecting return value from builder function
5. How can you extend a type-safe builder to support nested elements, for example adding a div inside body, while keeping type safety?
hard
A. Use a global div function outside the builder classes
B. Add a div property of type String to Body
C. Make Body inherit from Div
D. Define a div function inside Body that takes a lambda with receiver of a new Div class

Solution

  1. Step 1: Understand nested builder pattern

    To support nested elements, define functions inside builder classes that accept lambdas with receivers of nested element classes.
  2. Step 2: Apply to 'div' inside 'body'

    Inside Body, define a div function taking Div.() -> Unit lambda, creating a Div instance and applying the lambda to it.
  3. Final Answer:

    Define a div function inside Body that takes a lambda with receiver of a new Div class -> Option D
  4. Quick Check:

    Nested builders = functions with lambdas with receiver [OK]
Hint: Nested builders use functions with lambdas with receiver inside classes [OK]
Common Mistakes:
  • Using simple properties instead of nested builder functions
  • Trying inheritance instead of composition
  • Defining builder functions outside the class scope
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