Kotlin DSLs & Builder Patterns
Kotlin's scope functions and receiver lambdas enable elegant DSL patterns. Learn apply, buildList, and create custom DSLs.
apply for Object Initialization
The apply function returns the object after configuring it:
val user = User("Alice").apply {
age = 30
email = "alice@example.com"
isActive = true
}
Much cleaner than:
val user = User("Alice")
user.age = 30
user.email = "alice@example.com"
buildList & buildMap
Create collections with conditional items:
val features = buildList {
add("Login")
add("Profile")
if (isAdmin) add("Admin Panel")
if (isPremium) addAll(listOf("Analytics", "Export"))
}
val config = buildMap {
put("version", "1.0")
put("debug", isDebugBuild)
if (useCache) put("cache_ttl", 3600)
}
Custom DSL with Receiver Lambdas
Create a UI builder DSL:
class HtmlBuilder {
private val children = mutableListOf<String>()
fun p(text: String) { children.add("<p>$text</p>") }
fun h1(text: String) { children.add("<h1>$text</h1>") }
fun button(text: String, action: String) {
children.add("<button onclick='$action'>$text</button>")
}
fun build() = children.joinToString("")
}
fun html(init: HtmlBuilder.() -> Unit): String {
return HtmlBuilder().apply(init).build()
}
val page = html {
h1("Welcome")
p("Click the button below")
button("Click Me", "handleClick()")
}
@DslMarker for Scope Control
Prevent scope nesting mistakes:
@DslMarker
annotation class HtmlDsl
@HtmlDsl
class HtmlBuilder {
fun h1(text: String) { }
fun p(init: HtmlBuilder.() -> Unit) { } // nested builder
}
Nested DSL Patterns
fun container(init: HtmlBuilder.() -> Unit) = HtmlBuilder().apply(init)
val layout = container {
h1("Title")
p {
// This works: inner builder context
}
}
DSLs make configuration expressive and type-safe.
8 production-ready Android app templates available on Gumroad.
Browse templates → Gumroad
Top comments (0)