You are on page 1of 8

Eclipse Xtend

A language made for Java developers.

Embrace Java ...

Java is a great platform and also the language has some nice features. Xtend is not meant to replace Java all together but to be a convenient alternative in situations where Java doesn't shine. Therefore Xtend ... compiles to readable Java code comes with state-of-the-art Eclipse tooling resembles Java's syntax reuses Java's type system is statically typed relies on the JDK as a library does classes only

... but kill the noise ...

In contrast to Java, Xtend removes unnecessary noise. Reducing code to the minimum not only helps you type less, but more important makes the code more readable and maintainable. Boilerplate is mainly avoided by the following features: type inference property access better defaults optional semicolons optional parenthesis

... and add some sugar!

Simply improving on Java by removing the noise is already very helpful, but Java also lacks some important language features. Therefore Xtend adds the following features, which you will love once you got your hands on them. closures powerful switch expression template expressions extension methods multiple dispatch operator overloading

1 of 8

11/10/2011 10:55 PM

Eclipse Xtend

You need a running Eclipse including the Java Development Tools (JDT). To install the Xtend plugins open the update manager and paste one of the URLs on the right into the field 'Work with' and select the Xtend SDK.



: : :

If you want to get your hands on it, we recommend to materialize the tutorial example using Eclipse's example wizard. To do so in the IDE click:

You might want to have a look at what's on this page first. To get more detailed information about the various languae features you can have a look at the reference documentation. In addition to the pdf version it's also included in Xtext's html documentation.

-> NEW -> EXAMPLE...

The project consists of a bunch of Xtend files. Each of them illustrates a certain language feature and they are named accordingly. Those sample files contain a lot of working code snippets with some explanation in the comments. Just try it, it's straight forward.

Xtend compiles to readable Java code

Instead of generating bytecode directly, you get Java source code you can actually look at and debug through if you want. Compilation is done incrementally whenever you save a file in Eclipse just like with Java. The tooling makes sure you can navigate to the generated code as well as to the original Xtend code even when it is called from Java.

2 of 8

11/10/2011 10:55 PM

Eclipse Xtend

State of the art Eclipse tooling

Xtend was designed and developed together with the IDE support. The Eclipse support is deeply integrated with Java's development tools in Eclipse, such that the development experience is a seamless as possible. The Eclipse plug-in comes with almost all the features you are used to from the Java IDE : syntax coloring content assist rename refactoring organize imports quick fixes rich hover outline views navigation (go to declaration, find feferences, etc.) open type incremental compilation bracket matching mark occurences ... and many more

Java type system It's the one you know!

Static typing is great because it allows for better static analysis and much better tooling based on type information. The downside, however, is the extra complexity of a (static) type system. Although Java's type system might not be perfect, it is widely used and well understood. That's why Xtend reuses just everything about it. In contrast to Java, however, one seldomly has to write types down because of Xtend's support for type inference.
// qualified names java.lang.Object // primitives boolean, int, long, char, ... // arrays String[] // generics List<? extends CharSequence> java.util.Map<String,String>

Xtend just does classes and nothing else

Interface definitions in Java are already nice and concise. They have a decent default visibility and also in other areas there is very little to improve. Given all That's why Xtend can do classes only and relies on interfaces, annotations and enums being defined in Java. Xtend is really not meant to replace Java but to

3 of 8

11/10/2011 10:55 PM

Eclipse Xtend

annotation types.

4 of 8

11/10/2011 10:55 PM

Eclipse Xtend

Type inference Get rid of the redundancy

A lot of the information written down in a Java file is actually technically redundant. In the following Java example, the type of the variable could already be determined from the right hand side.
//Java List<String> names = getTheListOfNames()

Variable Declarations
val names = getTheListOfNames() val List<String> names = getTheListOfNames()

for (name : getTheListOfNames()) // do something with name for (String name : getTheListOfNames()) // do something with name

It's sometimes a good idea to write the type nevertheless, but most of the time it's just redundant noise and distracting the reader. Xtend doesn't force you to write the type everywhere, but you still can, if you want.

Return types
def getTheListOfNames() { newArrayList("Tomte","Pippi","Carlson") } def List<String> getTheListOfNames() { newArrayList("Tomte","Pippi","Carlson") }

getTheListOfNames().map( name | "Mr. "+name ) getTheListOfNames().map( String name | "Mr. "+name )

More noise reduction

Property access
Getter methods can be called using the Java property syntax. For example, you can write

Parenthesis for method invocations are optional, if the method does not take any arguments.

instead of

instead of

This also works great for setters and assignments. = "Foo"

Semicolons are optional and even the return keyword doesn't need to be specified. The result of the last expression in a method definition is treated as the implicit return value.

is equivalent to

Where is the sugar?

Closures finally!

5 of 8

11/10/2011 10:55 PM

Eclipse Xtend

names from persons in a list in in Java, you would typically write:

//Java List<String> names = new ArrayList<String>(); for (String name : persons) { names.add(name); }

with extension methods they allow to define nice builder APIs:

html [ head [ title [$("XML encoding with Xtend")] ] body [ h1 [$("XML encoding with Xtend")] p [$("this format can be used as an alternative to XML")] // an element with attributes and text content a("") [$("Xtend")] // mixed content p [ $("This is some") b[$("mixed")] $("text. For more see the") a("")[$("Xtext")] $("project") ] p [$("some text")] // content generated from arguments p [ for (arg : args) $(arg) ] ] ]

In Xtend you can just use the map extension method, which is available on every instance of java.lang.Iterable and pass it a closure : p | )

Although closures have a Java compatible type, Xtend provides a nicer notation for function types. The following example defines a closure which would be useful to filter a list of persons by a specific name.
val (Person) => Boolean predicate = [ person | "Hans" == ]

You usually don't have to write the types for functions that often, but would write instead:
val predicate = [ Person person | "Hans" == ]

Such a function can be passed to the extension method Iterable.filter((T) => Boolean):

Switch expression 'cause pattern matching is complicated

The switch statement in Java is a relict from C and has strange and errorprone semantics. At the same time it is almost useless in today's programming. Xtend comes with a switch expression, which is very convenient and different from what a switch means in Java: switch on anything using equals no fall through! it checks in the defined order supports type guards In the following example we have a type hierarchy, consisting of a type Shape which is extended by Rectangle and Circle. We use the switch with type guards to create a descriptive string for the different shapes. Note, that right after the type guard, the variable shape is automatically typed to the respective type. No down casting is neccessary and no ClassCastExceptions can ever happen.
val Shape shape = ... switch (shape) { Rectangle case shape.width == shape.height : "Square ("+shape.width+")" Rectangle : "Rectangle ("+shape.width+" x "+shape.height+")" Circle : "Circle ("+shape.diameter+")" default : "Don't know" }

Type guards
Type guards let you switch (or match) for types, which is much nicer and less errorprone than the usual lengthy instanceof-cascades we write in Java. In practice it is almost as useful as pattern matching but without introducing all the additional complexity.

Template expressions with a unique way of whitespace handling

Java's support for string literals and string concatenation is very limited. It lacks multi-line string literals and although the string concatenation using the plus operator is better then using method invocations it's often recommended to use

Hello World using JAX-RS and templates

A small example using JAX-RS API. The greyspace will go into the result.

6 of 8

11/10/2011 10:55 PM

Eclipse Xtend

In Xtend all string literals can span multiple lines by default. Also you can use single quotes or double quotes, to minimize the needd for escape sequences. If you have some text containing a lot of double quotes better use the single quoted string literal and vice versa:
val msg = 'This is some multi line text with "double quotes" in it'

Template expressions can do more than plain multi-line strings. They allow interpolating expressions and support a FOR-loop and an IF-statement. The most compelling feature is however the automatic whitespace handling!

Whitespace and Greyspace

A typical problem in text generation is, that you want to generate nice looking output with proper whitespaces and indentation. However, at the same time you want the template to be nicely indented. Therefore until now, templates either looked great and the output looked bad, or vice versa. Xtend can do better. It detects what whitespace is meant to indent the template code and what is meant to indent the output code using an algorthm which feels surprisingly intuitive. To help developers understand how Xtend handles whitespace, the editor supports coloring for the different kinds of whitespace.

Extension methods
Xtend got its name from the great support for extending existing types using extension methods. Extension methods allow to add new methods to existing types without touching them. In Xtend local methods are always available as extension methods and are available on the member scope of the first argument's type. Given the following method definition ...
/** * will be available as extension method locally. */ def getFullName(Person p) { p.firstName + " " + p.lastName }

Extension methods and injection

The real fun begins when you use the extension keyword on fields together with some dependency injection framework (we recommend Guice):
@Inject extension PersonExtension /* no field name */ def example(Person p) { // calls PersonExtension#getFullName(Person) on // the injected instance println( p.fullName ) }

you can write


This way you can define layer-specific libraries for your domain model, without poluting the model. And the best thing is, you can easily change the implementation without touching the code. All you need to do is to change the configuration of the dependency injection container. If you wonder how you get polymorphism into this, that's what multiple dispatch is for.

, which will be translated to and is the same as


. So it's basically syntactic sugar, but it reads better and the content assist in the IDE can be much more helpful.

Static extensions
Xtend puts a couple of default extension methods on the scope by default. They are mostly higher-order functions for Java's collection library. However, you can use any existing static method as an extension method if you use the keyword extension in the static import:
import static extension java.util.Collections.*

Multiple dispatch no more visitors!

Everybody knows the visitor pattern. However, Xtend also allows for a set of overloaded methods to do the

7 of 8

11/10/2011 10:55 PM

Eclipse Xtend

Wikipedia, November 2011

The visitor pattern is actually a work-around for the lack of multiple dispatch. By default Xtend (like Java) links overloaded methods at compile time based on the static types of the arguments:
def example() { val Shape s = new Rectangle() println(s.label) // prints "some shape" val Rectangle r = new Rectangle() println(r.label) // prints "a rectangle" } def label(Shape s) { "some shape" } def label(Rectangle r) { "a rectangle" }

def example() { val Shape s = new Rectangle() println(s.label) // prints "a rectangle" !!! val Rectangle r = new Rectangle() println(r.label) // prints "a rectangle" } def dispatch label(Shape s) { "some shape" } def dispatch label(Rectangle r) { "a rectangle" }

Note, that the multiple dispatch behavior is compiled into the declaration, so it will always behave the same no matter whether it's called from Java or Xtend.

8 of 8

11/10/2011 10:55 PM