Writing an idiomatic @resultBuilder requires defining “keyword-like” structs. For example, when you write ForEach in SwiftUI, what you’re actually seeing is something like this:
- there’s a
ForEachstruct (defined in SwiftUI) - there’s a
ViewBuilderresult-builder (defined in SwiftUI) - the
ViewBuilderhasbuildExpressionoverload that takes aForEachvalue
In addition to SwiftUI’s ForEach, there’s also RegexBuilder’s ZeroOrMore, OneOrMore, and ChoiceOf, as well as Square’s Predicate’s Or and And.
All of these are great ergonomics and yield a very DSL-like feel, but there’s a catch: all of these keyword-like structs are living in their module’s top-level namespace, which introduces a real risk of name collisions.
For example, you make your own ContentValidation builder, you want it to include its own ChoiceOf, and you want it to use Swift’s native regexes in its validation rules…and now you likely have to prefix each ChoiceOf with its module name.
The same would be true if you wanted to use your own ForEach in a project using SwiftUI, and so on—no need to belabor the point.
In any case, compiler-level solutions have already been proposed and discussed, but don’t seem to have any forward momentum.