Friday, October 16, 2009

LambdaJ new trends in Java

I must say I really enjoy the presentations from the JUGS. Couple of days ago there was another one about lambdaj, presented by its author Mario Fusco. He is a big fan of Scala and that's why he wanted to bring this functional way of doing things to Java.

I think this is a trend and we are going to see this more and more. It all started with the dynamic languages built on the JVM and now more and more people want functional things. I guess it has to do with the fact that Java the language did not see much change over the last 8 years, and people see solutions that are nice for specific problems in other languages. For instance Rails, it's very good in solving one particular problem and the Java community did notice that. Not only did it get ported to run on the JVM it also brought us Groovy/Grails.

So the latest thing in Java land is functional programming. There are some things one could solve more "elegantly" by using a language that is functional in nature. An example of this is filtering collections, this is what lambdaj tries to do, making standard Java behave in a more function manner.

To give a couple of examples. To filter a list of beans in lambdaj you could write something like this:
 
int totalAge = sum(meAndMyFriends, on(Person.class).getAge());

This will work because you would do a static import of the Lambda class that has the sum and on methods. So to explain what happens, the sum method will iterate over the collection of Person objects and invoke the getAge() method and sum all the results. Actually it's very readable what will happen. Because the on method uses generics you'll even get code completion and you'll be able to use refactoring.

Even better is the sumFrom method, it will return a bean of the same type of your list and you can then call any method to get the sum from all the properties. Of course this will only work if your collection contains object instances, because java generics are not reified.

Person totalsPerson = sumFrom(meAndMyFriends);
int totalAge = totalsPerson.getAge();
int totalLength = totalsPerson.getLength();

This works because sumFrom gives back a Proxy object that is the same as the elements in the list. When you invoke a method on it, it still has a reference to the list so it will iterate over the list and sum the properties.

Another example:

  
List<Person> oldFriends = filter(having(on(Person.class).getAge(), greaterThan(30)), meAndMyFriends);

There are of course more frameworks that can do similar things. When I first saw this I thought of jxpath but the disadvantage of this framework is that when doing refactoring, you'll have to manually change the xpath queries. Another powerful framework that also takes advantage of functional paradigm is google collections.

But as Mario Fusco also pointed out at the end of his presentation.... If you can, you should really give Scala a spin. Then you will not need lambdaj, you will have something more powerful.

No comments: