Tuesday, November 22, 2011

What’s So Special About Xtend’s Extension Methods?

You should read this, if you are :

  • interested in new programming language concepts
  • understood how great dependency injection is
  • want to learn about some uniqueness in Eclipse Xtend

Extension Methods

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. In C# extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. (Wikipedia November 2011)

In Xtend you could, for instance, add a new method to java.util.List like this:

def static <T> T head(List<T> list) {

  for (element : list)

    return element

  return null

}

Which then can be used as an extension method on any instance of Iterable<T>:

newArrayList(“foo”,”bar”).head()

Using the prefix notation is much closer to how we think, read, and write. From left to right that is. Also the IDE can now provide useful proposals because the receiver is known. The readability gets even better if you use chained method invocations. For instance, let's assume you want to filter the list before obtaining the head. Using the regular infix syntax known from Java the code would like like that :

head(filter(newArrayList(“foo”,”bar”) , [e | e != “foo”]))

But reading inside out doesn’t seem to be the best way to understand what’s going on. So better use extension methods:

newArrayList(“foo”,”bar”).filter(e | e != “foo”).head

Much better, isn't it?


Static Methods Are Bad!

But wait, don’t extension methods advocate the heavy use of static methods? And isn’t that bad coding style?

Yes, often it is.

With static methods you’ll bind your code not only to the signature of a certain method but to the actual implementation. There’s no way (aside from byte code manipulation) to change the implementation without touching the client code. That’s probably not a big deal with the kind of extension methods I just showed. But what if you want to have DAO-like methods available on your domain model types? Accessing them in a static way seems totally uncool, since we wouldn’t be able to run the code with mocks or exchange the database layer easily or just fix or change something later on. That's why static methods are a bad choice most of the time.

Typically you would want to use a dependency injection container to have such services injected. This is where Xtend’s extension methods are different from the one you find in C#.

Xtend allows to use methods from local fields as extension methods.

Let’s assume we have the following Java interface:

interface SaveSupport {

  void save(Entity entity);

}

And given we have some domain model type Person which implements Entity, you can write the following code:

class Controller {


  @Inject extension SaveSupport


  def testStuff() {

    val p = new Person()

    p.name = “Fred Flintstone”

    p.save // translated to ‘this._saveSupport.save(p)’

  }

}

That’s a big deal, because now you can use an object oriented coding style but keep your domain model free from layer specific code at the same time! And everything is easily testable and can be run in different scenarios using different DI configuration. There are other unique language features in Xtend, like the template expression, but the combination of extension methods and a good dependency injection framework (Guice) really changes how you structure your software system and reason about it.

Friday, November 04, 2011

New Xtend Website

With the recent release of Xtext 2.1, also the language Xtend got improved in various ways.
Today we announce a new landing page for Xtend:


So go find out about this little Java-enhancer and if you happen to be at EclipseCon Europe today 
make sure to attend Sebastian's talk on Xtend.
   
    Theater Stage at 2 p.m.

Tuesday, November 01, 2011

Build Your Own JVM Language!

Xtext has already simplified development of domain-specific languages a lot. From a simple grammar definition you not only get a full language infrastructure but also powerful Eclipse-based tool support.
Now it's getting even better.

Today we release Xtext 2.1, which comes with surprisingly easy to use support for defining little languages targeting the JVM (Java Virtual Machine). You only need to define two files:
  • the grammar
  • a mapping to Java concepts
The first one is not new. It's still the same concise and readable grammar language we always had in Xtext.

The second script is the big deal: it allows you to map your language concepts to any number of Java types, fields and methods. By doing that you implicitly tell the framework what it needs to know to provide you with a fully working IDE including an incremental compiler!

We have written a nice little tutorial explaining the five steps needed to get a language like the following:

import java.util.List

package my.model {

    entity Person {
        name: String
        firstName: String
        friends: List<Person>
        address : Address

        op getFullName() : String {
            return firstName + " " + name;
        }
        
        op getFriendsSortedByFullName() : List<Person> {
            return friends.sortBy( f | f.fullName);
        }
    }
    
    entity Address {
        street: String
        zip: String
        city: String
    }
}

As you can see, it supports all kinds of advanced features such as Java generics and full expressions even including closures. But you not only get a working parser, linker and compiler but a fully-working high-end Eclipse plug-in on top! The screencast demos the resulting language and IDE and briefly shows how that can be built. Be creative and have fun!