Showing posts with label Guice. Show all posts
Showing posts with label Guice. Show all posts

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.

Monday, March 21, 2011

A Guice Modules DSL

[Update] The code is available at github

Yesterday Sebastian and I were attending GuiceCon. A nice little get-together with the Guice developers and some very smart Guice users. As Guice is key in Xtext's architecture we took the opportunity to show the people what we do with it. The first idea was to just explain how we use Guice, but while we travelled across California last week a better idea came up : We could develop a Guice Modules DSL using Xtext.

So we did and we did it from scratch right in front of the audience without any tricks or shortcuts. The good thing was that everyone in the room knew the domain very well, so we didn't need to explain anything about the domain of the language.
First I defined the grammar and a first shot on the code generator and then Sebastian added type conformance checks and improved content assist. Today I've spent another two hours on it. The screencast below demos the status quo.

Note that there will be an extended tutorial at EclipseCon this Thursday, where you can learn how to create such things yourself in no time. Not to forget the short talk on "What's new in Xtext 2.0", Tuesday 2 pm.

Have fun!