Sonntag, 19. Oktober 2014

Xtend - Extension Methods

This is the feature that gave Xtend its name and one of its most powerful tools. At the same time it is one of the least understood features among beginners, so I'll give you a head start.

Extension methods can be called on instances of their first parameter type as if they were defined in that type. That's quite a mouthful, so let's just look at an example:

We defined an isPrime method that takes an int and then we could call 2.isPrime. You can extend any existing type this way. But which methods exactly are available as extension methods? As you have seen in the example above, instance methods of the current class are automatically available as extension methods. But many times you will want to write an extension once and then use it wherever you need it.

The simplest approach is to have static methods and import those using a static extension import. Doing this, these methods are available as extension methods in the whole file.

But often times you don't want static methods. Maybe because the helper method lives in a stateful object. Or maybe because you want to use a service that you get through dependency injection. For these cases you can also mark fields, parameters and even local variables as extensions. Their methods are then available as extension methods wherever the field/parameter/variable itself is visible. Below is an example of an extension field, maybe initialized in the constructor.

This makes typical OO patterns look much cleaner in Xtend. We all know that we should follow principles like "Single Responsibility". But in Java, calling these helpers is annoyingly verbose:

Another common pattern are factory methods and the Master-Yoda language that you use in Java.

In Xtend, using a static extension import, we get much closer to English.

And of course you sometimes need to use APIs that are just inconvenient. The only workaround in Java is creating wrapper classes that hide the bad API. But that of course adds runtime overhead for wrapping/unwrapping. With Xtend you can write some convenient extension methods and avoid this overhead completely.

Notice how there is no more syntactic difference between a normal method and a helper method. This makes for much more readable call chains.

To top it off, Xtend ships a small library with useful extension methods for classes from the JDK. Most importantly these include methods like filter, map and reduce to work with collections in a functional style.