Building mini-DSLs with result builders
Build a tiny DSL using @resultBuilder : define builder functions, compose blocks, and support conditionals/loops for readable construction.
Why result builders?
Goal: Turn readable blocks into values using @resultBuilder. You define how items combine; the call site stays clean and declarative.
A tiny builder
We declare buildBlock to join items and expose an API (lines{}) that returns an array of strings from a clean block.
@resultBuilder
struct StringListBuilder {
static func buildBlock(_ parts: String...) -> [String] { parts }
// Optional support for conditionals/arrays:
static func buildEither(first: [String]) -> [String] { first }
static func buildEither(second: [String]) -> [String] { second }
static func buildArray(_ components: [[String]]) -> [String] { components.flatMap { $0 } }
}
// DSL entry function using the builder
func lines(@StringListBuilder _ content: () -> [String]) -> [String] {
content()
}
// Usage: create an array of strings with a block
let list = lines {
"Hello"
"Swift"
"Builders"
}
print(list)All lessons in this course
- Building mini-DSLs with result builders
- Scoped APIs & readability patterns
- Practical examples without UI frameworks