Freitag, 24. Oktober 2014

Xtend - Perfect for Code generation

Before Xtend became a general purpose language, it was designed for building code generators and model-to-model transformations in the Xtext framework. And even though this is no longer Xtend's main focus, the related features are useful in other situations, too!

Template Expressions


Pretty much every modern language has some way to insert variables into a String template. In Xtend this is called a Rich String and has the following syntax:


But Xtend doesn't just have placeholders. You can have loops and branches right inside your templates. In other languages you need to go back to the StringBuilder pattern to do that.


Notice the different coloring in the whitespace above? Some of it is white, while other pieces are grey. This is how Xtend solves the classic "indentation problem". In  most other languages, either your template looks nicely formatted and the generated code is ugly or the other way round. But Xtend is clever enough to notice the difference between indentation in the generated code ("greyspace") and indentation that is just there to make the template look nice ("whitespace").

Template expressions will come in handy later on when we build Active Annotations to teach the Xtend compiler new tricks. Stay tuned for that!

Dynamic Dispatch


Just like Java, Xtend does static dispatch by default. If you have overloaded methods, the argument types known at compile time decide which is chosen. But sometimes you want to defer that decision to runtime. For instance, you might want to build a method that can convert different things to a Date. You pass in on Object and it tries its best to parse it. Possible valid inputs could be Date, Calendar, String, Long, etc.

To implement that in Java, you have to create a big if-else cascade to check the runtime types of the argument and then call the appropriate method.


Also, you have to be careful to put subtypes before supertypes so you don't end up with dead branches.


Xtend makes dynamic dispatch a first class concept. You just write down the different cases. Xtend then looks for the common supertype of the argument types. In this case it's java.lang.Object. Using that argument type, it generates the entry point method similar to what we did by hand in Java. This even works when subclasses add additional overloads. Also notice how we got rid of all the casts that the Java version had.


The toDate method was only a simple example to introduce the concept. Dispatch methods really shine when you build code generators, interpreters and other kinds of object tree visitors. Most of the time you don't know the exact type of the elements in that tree at compile time. With dispatch methods, you don't need to care, the correct method will be selected at runtime.