The concept of builders is rather popular in the Groovy community. Builders allow for defining data in a semi-declarative way. Builders are good for generating XML, laying out UI components, describing 3D scenes and more...
For many use cases, Kotlin allows to type-check builders, which makes them even more attractive than the dynamically-typed implementation made in Groovy itself.
For the rest of the cases, Kotlin supports [dynamic] builders.
A type-safe builder example
Consider the following code that is taken from here and slightly adapted:
fun result(args : Array<String>) = } // an element with attributes and text content // mixed content } // content generated by for (arg in args) } } }This is a completely legitimate Kotlin code. Click on names to navigate to definitions of function used in this example (they appear below in this page).
How it works
Let's walk through the mechanisms of implementing type safe builders in Kotlin. First of all we need to define the model we want to build, in this case we need to model HTML tags. It is easily done with a bunch of classes. For example, HTML is a class that describes the <html> tag, i.e. it defines children like <head> and <body>.
(See its declaration below.)
Now, let's recall why we can say something like this in the code:
html { // ... }This is actually a function call that takes a function literal as an argument (see this page for details). Actually, this function is defined as follows:
fun html(init : HTML.() -> Unit) : HTML { val html = HTML() html.init() return html }This function takes one parameter named init, which is itself a function. Actually, it is an extension function that has a receiver of type HTML (and returns nothing interesting, i.e. Unit). So, when we pass a function literal to as an argument to html, it is typed as an extension function literal, and there's this reference available:
html { this.head { /* ... */ } this.body { /* ... */ } }(head and body are member functions of HTML.)
Now, this can be omitted, as usual, and we get something that looks very much like a builder already:
html { head { /* ... */ } body { /* ... */ } }So, what does this call do? Let's look at the body of html function as defined above. It creates a new instance of HTML, then it initializes it by calling the function that is passed as an argument (in our example this boils down to calling body on the HTML instance), and then it returns this instance. This is exactly what a builder should do.
The head and body functions in the HTML class is defined similarly to html. The only difference is that they add the built instanced to the children collection of the enclosing HTML instance:
Actually these two functions do just the same thing, so we can have a generic version, initTag:
protected fun initTag<T : Element>(init : T.() -> Unit) : T where class object T : Factory<T> { val tag = T.create() tag.init() return tag }This function uses class objects to instantiate classes. It depends on the Factory class defined as follows:
abstract class Factory<T> { fun create() : T }Now, the classes Head and Body declare class objects that extend Factory, for example:
class Head() : TagWithText("head") { class object : Factory<Head> { override fun create() = Head() } // ... }So, now our functions are very simple:
fun head(init : Head.() -> Unit) = initTag(init) fun body(init : Body.() -> Unit) = initTag(init)And we can use them to build <head> and <body> tags.
One other thing to be discussed here is how we add text to tag bodies. In the example above we say something like
So basically, we just put a string inside a tag body, but there is this little "+" in front of it, do it is a function call that invokes a prefix "plus" operation. That operation is actually defined by an extension function plus that is a member of the TagWithText abstract class (a parent of Title):
So, what the prefix "+" does here is it wraps a string into an instance of TextElement and adds it to the children collection, so that it becomes a proper part of the tag tree.
All this is defined in a namespace html that is imported at the top of the builder example above. In the next section you can read through the full definition of this namespace.
Full definition of the html namespace
This is how the namespace html is defined (only the elements used in the example above). It builds an HTML tree. It makes heavy use of Extension functions and Extension function literals.
fun create() : T } protected fun initTag<T : Element>(init : T.() -> Unit) : T where class object T : Factory<T> { val tag = T.create() tag.init() return tag } } children.add(TextElement(this)) } } class object : Factory<HTML> { override fun create() = HTML() } } class object : Factory<Head> { override fun create() = Head() } } } class object : Factory<Body> { override fun create() = Body() } val a = initTag(init) a.href = href } } class B() : BodyTag("b") class P() : BodyTag("p") class H1() : BodyTag("h1") class A() : BodyTag("a") { var href : String } val html = HTML() html.init() return html } }Appendix. Making Java classes nicer
In the code above there's something that looks very nice:
class A() : BodyTag("a") { var href : String }We access the attributes map as if it were an "associative array": just with the [] operation. By convention this compiles to a call to get(K) or set(K, V), all right. But we said that attributes was a Java Map, i.e. it does NOT have a set(K, V). This problem is easily fixable in Kotlin:
fun <K, V> Map<K, V>.set(key : K, value : V) = this.put(key, value)So, we simply define an extension function set(K, V) that delegates to vanilla put and make a Kotlin operator available for a Java class.
What's next
Examples
Functions

18 Comments
comments.show.hideJul 20, 2011
Anonymous
See how they all (groovy builders, kotlin builders) all want Lisp (such as Clojure). They just don’t know it yet it seems.
Jul 28, 2011
lacroix1547
Type safe builders, this is really nice.
The document structure definition, if we can call it that way, is still verbose however.
I wonder what could be done with a little more sugar.
But this is not common to design the structure of something like Html even if we use it so much.
I have never done such a thing or see anybody do that.
Inserting tags inside text, this is not common outside of html like data.
Maybe with Svg, Vml, and the like.
However for json like data, I see potential uses every day.
Json syntax simplicity is hard not to like.
Doing the same thing in java, not really, this is syntactically impossible.
But in Kotlin, as far as I known the following code is valid syntax.
The Country and Province class definition are left as an exercice of course.
I havent seen the list literal syntax in the documentation yet, but I bet this is coming.
This is not just a bunch of map of map.
This is some type safe object notation.
That's right, this is some tson.
This is a really nice feature.
Actually it is 3 small features working together: named params, removing the "new" keyword and list literals.
That may still be improved.
No comma or allowing a trailing coma would make it easier to edit properties.
I always have to correct missing or extra commas in my jsons when I add, delete, shuffle and copy paste properties.
Also, maybe the Province constructor here could be infered, when the type of the containing list is not abstract.
Jul 27, 2011
Andrey Breslav
Thanks for your suggestion
Aug 11, 2011
Alex Tkachman
Is it really necessary to specify type explicitly in initTag<B>(init) for example. It will be really nice if <B> can be infered
Aug 12, 2011
Andrey Breslav
While we are still working on the inference subsystem, I think we will be able to infer the types in this case.
Sep 25, 2011
Anonymous
The Unit fiction is one of the confusing things for people first learning Scala. I don't think it is necessary to create such an esoteric syntax. The html function (and child element functions) can take a variable argument list instead (or the last input parameter can be a variable argument list), then the braces get replaced with parenthesis and commas. Then one less thing to have to explain. I admire languages that have a consistent syntax with the least number of concepts to learn and memorize. What difference does it make:
html {
head {
title { ... }
}
body {... }
}
Or:
html (
head (
title ( ... )
),
body( ... )
)
The latter is immediately understand by any programmer from any background.
-Shelby Moore III
Sep 25, 2011
Andrey Breslav
I don't see how Unit is essential for the example studied in this section.
As of parameters vs function literal bodies, the key thing here is that which function literals you can intermix "markup" with code in the way you see in the last <p> element, and the context will be taken care of by the 'this' in the current function literal.
Sep 27, 2011
Anonymous
Using variable argument length function parameters, seems to me the entire example can be accomplished with constructor functions. For example, body can input a variable argument of type htmlelement, and paragraph a variable argument of the disjunction type (htmlelement or string). No need to ever introduce the concept of Unit. I saw someone else refer to Unit as "fiction" and then I realized this is probably what they meant. Perhaps I am wrong.
A disjunction type is very important: http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types/7460312#7460312
Sep 27, 2011
Andrey Breslav
I still don't get how absence or presence of Unit can possibly influence the HTML builder example.
As of the constructors story, please refer to the comment you were replying to.
Oct 07, 2011
Anonymous
Is there a way to get rid of the "+"? If the body should return Unit, could one infer the "+"?
Oct 07, 2011
Anonymous
The + was missing in my comment above in "...".
Oct 07, 2011
Andrey Breslav
I don't think we could literally infer the "+", because this means implicitly calling a function, which, if generalized, leads to very cumbersome code.
Note that "the '+' problem" only stands for HTML, and not for other builders that do not have "free" text in the built structure.
For HTML, you can get rid of "+" at expense of sacrificing some type safety: use varargs functions instead of functions taking functions as parameters. And this is basically what Groovy does here.
Oct 09, 2011
Guillaume Laforge
Just to comment on the "groovy-ness" of builders and type-safety, we can make Groovy builders as type-safe as we want. We can create a builder that only recognizes certain tags and forbids others. With the help of a compilation customizer or an AST transformation, we can even let the compiler report compilation errors if a non-allowed tag is used. Furthermore, with GDSL or DSLD file (whether one is on IntelliJ IDEA or Eclipse), we can even provide rich type-completion from the IDE for authoring such markup.
Also, the Groovy markup builder is used to create any markup (including namespaces), not just HTML. Your builder will have to be udpated should HTML 5, 6, 7, x, add new tags that are not recognized by the builder, whereas it's possible with Groovy's one.
That said, the use of + for free text is a good idea -- that could be adopted within the Groovy markup builder as well.
Apr 22, 2013
Mohammad Shamsi
in the following example, you can see I have added a new "head" within body and also another "body" call within the main "body".
Is there a way to restrict the calls and make sure only valid calls can happen ?
Apr 22, 2013
Andrey Breslav
You can define a deprecated method, say, "head" in the BodyTag class, so that the call will be highlighted for you. Currently there's no way to get a compiler error there, we are working on this.
May 07, 2013
Alexey Pomelov
Why don't you add an optional string parameter to the initTag method, that will be treated as a first text node? So we can change
with this one:
In my experience mixed content in html is rarely used.
May 07, 2013
Andrey Breslav
Yes, it's an option. The problem is not mixed content, but rather content generated by a few lines of code, though
May 07, 2013
Alexey Pomelov
Yeah, I see. Even so, imho, text nodes' values are often can be evaluated with a single expression.