Tuesday, July 13, 2010

Lambdas in Java Preview - Part 3: Collections API

This is the third part in a series of blog posts (read part 1, part 2 and part 4) giving some practical examples of lambdas, how functional programming in Java could look like and how lambdas could affect some of the well known libraries in Java land. In this part I'll focus on how the addition of lambdas could affect one of the most used standard APIs - the Collections API.

Note: While writing this post, a new proposal has been published, that uses a different syntax for lambdas, removes function types and uses more type inferencing. I'll post a short description of the changes soon. The new proposal would change some of the examples in this post, but the examples are still essentially valid and useful.


The Collections API is one of the most used APIs around in Java. Amongst its mostly used collection types are lists, sets and maps. Also the Collections class, which provides utility methods for operating on these collections is commonly used. The reason why I chose the Collections API as an example on how lambdas might influence existing APIs is that certain kinds of operations on collections can be written much more natural in a functional programming style than in an imperative style. This is also one of the reasons for the growing number of projects that aim to bring functional elements to Java in the form of libraries, e.g. Google Collections or lambdaj.

Status quo
One of the common operations on lists is filtering a list for elements matching a certain condition, say for example filtering a list of integers for the even ones. We could implement a method findEven like this:
List<Integer> findEven(List<Integer> list) {
  List<Integer> result = new ArrayList<Integer>();
  for (Integer n : list) {
    if (n % 2 == 0) result.add(n);
  }
  return result;
}
We can call it with a list of integers and it will return a list containing the even integers. Works just fine, but what if we'd also want a method that returns only the odd elements? There is no straight way of building an abstraction for that, so we'd write a method findOdd which would look 99.3865% the same as findEven.

Google Collections to the rescue we can use the Iterables.filter method which takes a list and filters it by a given Predicate.
Iterable<Integer> even = Iterables.filter(list,
  new Predicate<Integer>() {
    @Override
    public boolean apply(final Integer n) {
        return n % 2 == 0;
    }
  });
This filter method is way more flexible as it can take any predicate you like to filter by. But actually it really doesn't look nice, at least unless you build your own library of reusable predicates.

Simplification through lambdas
Now, if we have a look at it, the essential part of the predicate is just the expression n % 2 == 0. The rest is just boilerplate. With lambdas we can actually remove all(!) of this boilerplate. To do that, we implement a filter method quite similar to that of the Google Collections, but instead of taking a predicate of type Predicate as the second argument, it'll take the predicate as a lambda:
public static <T> List<T> filter(List<T> list, 
    #boolean(T) predicate) {
  List<T> result = new ArrayList<T>();
  for (T t : list) {
    if (predicate.(t)) result.add(t);
  }    
  return result;
}
Say we have implemented this filter method in a class called FCollections, calling it looks like this then:
List<Integer> list = Arrays.asList(4,3,2,6,4);
List<Integer> even = FCollections.filter(list, #(Integer n)(n % 2 == 0));
Compare that to calling the Google Collections filter method. It's much more concise, readable and expressive.

Extension methods
Before we have a look at more operations on collections of this sort, I want to mention a feature that will probably also be introduced in JDK7 - extension methods.

Notice that we have put our filter method in a utility class FCollections. But filter should probably rather be a method of List or Collection itself. Unfortunately, adding a new method to these interfaces would break existing sub classes of List or Collection, something we definitively wouldn't want. Now, extension methods allow for adding a new method to an interface and specifying a default implementation of this method:
public interface List<E> extends Collection<E> {
    
    List<E> filter(#Boolean(E) predicate) import static Collections<E>.filter;
    ...
Now, if a sub class of List doesn't implement a filter method itself Collections.filter is called by default. Collections.filter would look like our FCollections.filter method - it takes a list as the first argument followed by the predicate lambda and it must return a List.

So with extensions methods it would be possible to add new operations on collection types like those showed in this post without breaking existing sub classes (at least as long as these subclasses didn't implement an incompatible filter method before). But extension methods are not the primary topic of this post (search the web for extension methods or public defender methods for more details), let's go back and see some more useful operation on collections.

More operations
There's a bunch of operations that can be implemented in a more functional style, e.g. iterating a list and applying a function to each element.
public class MyList<T> extends ArrayList<T>
  
  public void each(#void(T) f) {
    for (T e : this) {
      f.(e);        
    }     
  }
Instead of iterating with a for loop, we can call the each method like this:
list.each(#(Integer n)(System.out.println(n)));
Another example is the map function that takes a function, applies it to each element of the list and returns the result as a list:
public <S> List<S> map(#S(T) f) {
  List<S> result = new List<S>();
    for (T e : this) {
        result.add(f.(e));        
    }    
    return result;
}
We could use it to create a list of squares from a list of integers:
List<Integer> squares = list.map(#(Integer n)(n*n));
foldLeft is a another method that combines the elements of a list together using a function f from left to right (foldRight does the same from right to left) starting with a value z, i.e. the result is f(f(f(f(f(z,a1),a2),a3),a4),a5)
public <S> S foldLeft(S z, #S(S, T) f) {
    S acc = z;
    for (T e : this) {
        acc = f.(acc, e);
    }    
    return acc;
}
A simple way to use it would be to calculate the sum of the elements:
Integer sum = list.foldLeft(new Integer(0), #(Integer a, Integer b)(a+b));
reduce does the same, but without an initial value.
public T reduceLeft(#T(T, T) f) {
    if (isEmpty()) throw new UnsupportedOperationException("reduce on empty list"); 
    if (size() == 1) return get(0);

    T acc = get(0);
    for (T e : subList(1, size())) {
        acc = f.(acc, e);
    }    
    return acc;
}
Integer sum = list.reduceLeft(#(Integer a, Integer b)(a+b));
The find method searches for the first element matching a given predicate and returns it:
public T find(#Boolean(T) predicate) {
    for (T e : this) {
        if (predicate.(e)) return e;
    }    
    return null;
}
Integer found = list.find(#(Integer n)(n>5));
There are many more possibilities to use predicates in this way, here are some short examples:
boolean hasPrime = list.exists(#(Integer n)(isPrime(n));
boolean allPrimes = list.forall(#(Integer n)(isPrime(n));
boolean countPrimes = list.count(#(Integer n)(isPrime(n));
boolean withoutPrimes = list.remove(#(Integer n)(isPrime(n));
Pair<List<Integer>> oddAndEven = list.partition(#(Integer n)(n%2==0));

To summarize, as you can see the Collections API could benefit in a lot of ways from the addition of lambdas. For some sort of operations, lambdas would increase readability, conciseness and expressiveness. Extension methods could make it possible to have some of the new operations directly in the collection classes instead of in utility classes like Collections.




Monday, July 5, 2010

Lambdas in Java Preview - Part 2: Functional Java

This is the second part in a series of blog posts (read part I) giving some practical examples of lambdas, how functional programming in Java could look like and how lambdas could affect some of the well known libraries in Java land. This part focusses on general functional programming techniques, which will be available through the addition of lambdas. Functional programming (although I still wouldn't consider Java a functional programming language) will make Java code more concise, more expressive and more readable in certain kinds of problem situations.

Note: All the following examples work with the current prototype implementation of lambdas.

Simplifying code
Let's start with a simple example that shows how higher-order functions in general can lead to simplified code. Suppose we want to search for files of a certain type. Up to now, we would probably use a FileFilter:
File dir = new File(".");

File[] files = new File(".").listFiles(new FileFilter() {
    public boolean accept(File file) {
        return file.getName().endsWith(".java");
    }
});
But with higher-order functions we could write a method that takes the filtering logic as a function argument. Think of this code as being part of an API.
public static File[] fileFilter(File dir, #boolean(File) matcher) {
    List<File> files = new ArrayList<File>();
    for (File f : dir.listFiles()) {
        if (matcher.(f)) files.add(f);
    }
    return files.toArray(new File[files.size()]);
}
The client code of this API would be a one-liner then:
File[] files = fileFilter(dir, #(File f)(f.getName().endsWith(".java")));
Callback mechanisms like filtering files with a FileFilter like above can generally be greatly improved by replacing the callback class with a function. And in fact, callbacks with only one method are so common in Java, that there will be special support for so called SAM types (single abstract method, see also first part of this series) from project lambda. This allows us to call the existing File.listFiles(FileFilter) method with a function instead of a FileFilter. Because FileFilter is a SAM type, the function will automatically converted into a FileFilter then:
File[] files = dir.listFiles(#(File f)(f.getName().endsWith(".java")));

Currying
One of the features most functional languages support (some even make very excessive use of it) is currying. Currying allows for defining a function with multiple parameters and allow the client to call it with fewer parameters, which will return a function in which the given parameters are fixed. A simple example would be a function that takes two parameters x and y and returns the sum. The client could the call this function with a fixed value for x, say 5, but without a value for y. This would result in a function that takes one parameter y and returns 5+y. Let's try to implement this curried function in Java:
##int(int)(int) sum = #(final int x)(#(int y)(x+y));
assert sum.(3).(5) == 8;

#int(int) add5 = sum.(5);
assert add5.(4) == 9;
Here we first define a function sum of type ##int(int)(int), i.e. of type function that takes an integer and returns a function of type #int(int). We can evaluate this in a single statement sum.(3).(5). The first call sum.(3) will basically result in a lambda expression #int(int y)(3+y). The second call will evaluate this expression passing 5 as the value for y. But instead of evaluating the whole expression, we can also evaluate it partially, as in line 4. This will result in a function add5, that could be called with different values of y and would return 5+y.

That's what currying in Java could look like. Agreed, it looks nicer in other languages, but it generally works. Maybe some syntactical sugar could still be added.

Control Abstractions
Another feature of many functional languages is the possibility to build control abstractions that look like natural syntax. This is made possible through currying and higher-order functions in general. Let's have a look at a simple example.
##void(#void())(int) afterDelay = #(final int n) {
  return #(#void() f) {
    try {
      Thread.sleep(n*1000);
      f.();
    } catch (Exception e) {}
  };
};
afterDelay is a higher-order function, it takes an integer n as argument and returns a function that takes a function f. The returned function will execute f after n seconds. We can invoke it directly like
afterDelay.(2).(#()(System.out.println("foo")));
which will print "foo" to the console after waiting for two seconds. Or we can make use of currying to create another function after5Seconds, which is a function that takes another function and evaluates it after waiting for 5 seconds.
#void(#void()) after5Seconds = afterDelay.(5);

after5Seconds.(#()(System.out.println("foo")));
after5Seconds.(#()(System.out.println("bar")));
Now this still looks like a normal function call and not like a control abstraction, yet. But it is simple to make it look like one. Just replace the parentheses with curly braces
after5Seconds.(#() {
    System.out.println("foo");
    System.out.println("bar");
});
and it almost looks like other control structures like for or if.

Now, let's have a look at another example that demonstrates the loan pattern:
##void(#void(PrintWriter))(File) withWriter = 
  #(final File file) {
    return #(#void(PrintWriter) doWithWriter) {
      PrintWriter writer = null;
        try {
          writer = new PrintWriter(file);
          doWithWriter.(writer);
        } catch (Exception e) {
          // Just ignore exceptions, see straw-man
          // proposal for exception handling with 
          // lambdas
        } finally {
          if (writer != null) { 
            writer.close();
          }      
        }
    };
};
Simply said, withPrintWriter is a function that takes a file as its argument and opens a PrintWriter on that file. Then it calls a function given by the caller with this PrintWriter (or loans it to the function). Things will probably get a lot clearer having a look at how to call withPrintWriter.
File file = new File("log.txt");

withWriter.(file).(#(PrintWriter writer) {
    // Printing to the file
    writer.println("foo");
    for (int i=0;i<10;i++) writer.println(i);
});         
As withWriter is a curried function, we can evaluate it partially (just with a file) and assign the result to a variable of function type, which can be called multiple times.
#void(#void(PrintWriter)) logger = withWriter.(file);

logger.(#(PrintWriter writer) {
    writer.println("foo");
});         
logger.(#(PrintWriter writer) {
    for (int i=0;i<10;i++) writer.println(i);
});
Note, withWriter can also be implemented as a non-curried function. We could pass the function directly as a second argument to it.
#void(File, #void(PrintWriter)) withWriter = 
  #(final File file, 
      final #void(PrintWriter) doWithWriter) {
    PrintWriter writer = null;
    try {
      writer = new PrintWriter(file);
      doWithWriter.(writer);
    } catch (Exception e) {
    } finally {...}  
  }
};

withWriter.(new File("log.txt"), #(PrintWriter writer) {
  writer.println("Hello ");
  writer.println("World.");
});         
This kind of control abstractions can be very useful for code reuse, e.g. to remove boilerplate code in resource handling (withWriter, withReader, ...) or transaction handling (inTransaction).

For the fun of it let's do another example, which simplifies reading the lines of a file one by one:

#void(File, #void(String)) eachLine = 
  #(final File file, final #void(String) fun) {
    FileInputStream in = null;
    try {
      in = new FileInputStream(file);
      BufferedReader reader = 
        new BufferedReader(new InputStreamReader(in));
      String line = null;
      while((line = reader.readLine()) != null) {
        fun.(line);
      }
    } catch (Exception e) {
    } finally { /* close in */ }      
  }

};
Again, think of eachLine as being part of an API, hidden from the client. On the client side things get really easy.
File file = new File("log.txt");

eachLine.(file, #(String line) {
  System.out.println(line);
});
In fact eachLine should probably be part of the class File itself. And maybe it will get in there in JDK7 via an extension method (which is a topic of a following post).

Originally, I didn't plan to write that much about control abstractions (it's just too much fun, though), but instead cover recursion as a functional technique, too.

Recursion
Unfortunately, until now it's not quite clear how recursive calls in lambda expressions would look like or if it will even be possible to write recursive lambdas (if it wasn't possible we could still call recursive methods from a lambda). There are currently some discussions going on the project lambda mailing list, so I'll skip this topic for now.


To summarize, functional techniques allow for some code simplifications in certain scenarios as described above. Actually, this was also the primary reason to introduce lambda expresssions, namely for simplifying code for the new fork/join framework and parallel arrays. But lambdas make it possible to simplify code in a lot of other use cases as well.

Wednesday, June 30, 2010

Lambdas in Java Preview - Part 1: The Basics

As announced at Devoxx last year, closures (or better lambda expressions) will (probably) be added to JDK7. The team of project lambda has checked in initial parts of the implementation into the OpenJDK repositories. This is the first part (see part 2) in a series of blog posts giving some practical examples of lambdas, how functional programming in Java could look like and how lambdas could affect some of the well known libraries in Java land. Although most of the examples will work with the current prototype implementation, keep in mind, that this is just a preview, which is based on the straw-man proposal, the specification draft, the discussions on the project lambda mailing list and the current state of the prototype. There might/will be both semantical and syntactical differences to the final version of lambdas in Java. Also some details are left out, e.g. exception handling will probably be out of scope.

The focus of this series is on practical usage of lambdas, not in principal on the fundamental concepts of lambdas. You don't need to have any theoretical knowledge of lambda calculus or a strong background in functional programming. And don't break your mind on what closures are, just think of them as anonymous functions or code blocks that can be passed around. But despite you don't need to know about all this, I don't want to discourage you from researching these topics.

Note: If you want to try out some examples there's a little trick to get the lambda prototype working, see here.

Lambda expressions
To get started, let's have a look at a very simple example of an anonymous function or "lambda expression". The following is a lambda expression that takes an integer x and returns 2*x:
#(int x)(2*x)
The hash symbol introduces the lambda expression, or "function literal". The first pair of parentheses is a comma-separated argument list and the second pair of parentheses encloses the expression, which is evaluated on invocation. Here is another example of a lambda expression, that takes two arguments x and y and returns their sum:
#(int x, int y)(x+y)
What we would naturally do with a lambda expression is to evaluate it. We could directly invoke one of the function literals above directly with #(int x)(2*x).(7), but this will probably be a bit uncommon.

Function types
Instead invocation will mostly happen on variables of a function type. So we first bind a function to variable and do the invocation on that. The syntax for function types is very similar to the syntax of function literals:
#int(int) doubler = #(int x)(2*x);
This declares a variable doubler of type #int(int), i.e. of type function that takes an int (in parentheses) and returns an int (after the #). Now, to invoke doubler we can write
int n = doubler.(3);
assert n == 6; 
Notice the dot before the parentheses. For another example, let's look at the sum lambda again:
#int(int, int) sum = #(int x, int y)(x+y);
int x = sum.(3, 7);
assert x == 10;
More complex expressions
So far the body of the lambda expressions was just a single expression. In this case it can be included in parentheses and the return keyword can be omitted. In the more complex case the body can be a block with curly braces and must explicitly return a value (if it's not void):
#int(int, int) max = #(int x, int y) {             
    if (x >= y) return x;
    else return y;
};
int z = max.(3,4);
assert z == 4;
Higher-order functions
Of course, functions can also be passed as arguments to methods and other functions. This will be the most common usage. A function, that takes an integer n and function f, that executes f n times could look like this:
public static void times(int n, #void(int) f) {
    for (int i=0;i<n;i++) {
        f.(i);
    }
}
The following will print the squares of 0 to 4 on the console.
times(5, #(int index)(System.out.println(index*index)));
Functions and methods can also have a function as their return value. The following method takes an integer x and returns a function that takes another integer y and returns x*y.
public static #int(int) multiplier(final int x) {
    return #(int y)(x*y);
}
The invocation looks like this:
#int(int) mult5 = multiplier(5);
assert 20 == mult5.(4);
This case also shows, that it is possible to capture variables from the enclosing scope (this is what makes it a closure by the way). x is a free variable and its definition is copied over into the body of the lambda expression at runtime. For this to work x must be declared effectively-final or shared (see straw-man proposal for details).

That's it
That's basically it for the fundamentals of lambda expression in Java. But you will probably have noticed by now, that it will have a huge impact on Java, both the language and the libraries.

Side note: Some people don't like the syntax of lambdas as above. I don't want to start the discussion here again, just two points. First, the syntax can actually be awkward in some cases, but most of the time it's just passing around functions as literals or variables, which doesn't look awkward. And second, because Java is a statically typed language and has features like checked exceptions and others, closures won't look like in dynamically typed languages or languages with strong type inferencing or languages without checked exceptions.

Function conversion
This last section is about function conversion, which isn't something that is essential to lambda expressions, but will also have a huge impact. Many Java libraries use so called SAM types (single abstract method) - interfaces with only a single method and abstract classes with only one abstract method. Function conversion means that a function of appropriate type can be converted into an anonymous instance of a SAM type as needed. For example, the Collections.sort method takes a List and a Comparator, which has a single abstract method int compare(T x, T y). Up to now this would look like this:
// This would be just '= [4,2,1,3]' 
// with collection literals
List<Integer> list = 
    Arrays.asList(new Integer[]{4,2,1,3});

Collections.sort(list, new Comparator<Integer>() {
    public int compare(Integer x, Integer y) {
        return -x.compareTo(y);
    }
});
But with function conversion we can substitute a function of appropriate type:
Collections.sort(list, 
    #(Integer x, Integer y)(-x.compareTo(y)));
This will probably be used very often, because SAM types are so common in the Java world. As a side note, an open questions to me is, if API designers should choose to take functions as arguments to their methods/functions or SAM types, which may be more flexible and more expressive.

Final example
For a final example we implement the Fibonacci function and call it several times in parallel threads.
class ParallelFib {

    final static #void(int,int) fib = 
        #(int c, int n) {
            int result = fib(n);
            System.out.println(c + ") " + 
                "fib(" + n + ") = " + result);
        };

    public static int fib(int n) {
        if (n == 0 || n == 1) return 1;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {  

        for (int i=0;i<10;i++) {
            final int i2 = i;
            new Thread(#()(fib.(i2, 32))).start();
        }    

    }

}
fib first occurs as a class variable of function type. This lambda expression takes a counter c and input n, calls the method fib (I don't know, if recursive lambda calls are possible at the moment) and then prints the counter and the result. The main method creates 10 threads each taking the fib lambda expression, which is converted implicitly into a Runnable. The output is something like this:
1) fib(32) = 3524578
3) fib(32) = 3524578
2) fib(32) = 3524578
0) fib(32) = 3524578
7) fib(32) = 3524578
4) fib(32) = 3524578
9) fib(32) = 3524578
6) fib(32) = 3524578
8) fib(32) = 3524578
5) fib(32) = 3524578
Feel free to post comments on what you think about lambdas right here, or give feedback directly to the members of project lambda, which I think is always welcome.

Monday, June 14, 2010

Eclipse Helios Preview for Java Developers

The final release of the new Eclipse 3.6 - Helios is coming close on June 23. Here is a short overview of some of the new features for Java developers.

Open Implementation
Open Implementation, which was available by holding Ctrl and hovering over a method in the editor, is now also available in the navigate menu and can be bound to a keyboard shortcut (e.g. F4?).


Expressions View
When debugging, it's now easier to add expressions in the expressions view and the expressions view has now columns


Breakpoints View
The breakpoint view now provides the possibility to quickly edit some properties of the breakpoint, e.g. breakpoint condition.

Dragging and linking files from operating system
You can now drag files from the operating system into the package explorer and instead of copying them there you can create just links. This feature is definitely useful in a lot of cases.


Move Type to New File Refactoring
Convert Member to Top Level Type has been renamed to Move Type to New File.


Javadoc includes annotations
This is a feature I've been waiting for quite long. The JavaDoc hovers now include information about annotations.

Tuesday, June 1, 2010

So you find Java 7 closure syntax nasty?

Two days ago Baptiste Wicht blogged about the first version of closures pushed by Oracle. He says "This syntax is a little bit shocking, but I think we’ll get used." and the comments to his post go like "Really ugly" and "terrible syntax". Same over at Java Posse Google Group: "closures are looking worse by the day", "I realllllly don't like the look of them", "Wow that's ugly. Source code obfuscaters are going to have a blast".

But let me ask one question: Why has it taken so long for the Java community to realize that? It's just a few month until JDK7 is going to be released, but the closure debate has been around for quite a long time now (not to say years). There were several proposals, there has been the straw-man proposal and the spec draft and the announcement last Devoxx. But there hasn't been much of a discussion in the community.

What is the reason for that? I have some assumptions. Has project lambda been too quiet? There weren't many blog posts or examples. Or is there something broken with the community? Were have the community leaders been? Are they too busy learning Scala? Or is it just that closures in a statically typed language (without type inferencing) are intrinsically complex?


And by the way, what about Java modularity?





Sunday, February 7, 2010

Groovy++ Performance - Now we're talkin'

This is a follow-up of my last post, where I compared the runtimes of the quicksort algorithm implemented in Java, Scala, Groovy and Groovy++. Groovy++ came up with a significant improvement over Groovy. But there was a comment by ait (Thanks ait) on how to improve the performance of the Groovy++ implementation even further, by changing a single line. In fact, this improved the performance dramatically.

In the previous post I showed the de-compiled byte code of the Groovy++ implementation of the algorithm. There were two things that were different from the Java byte code: array access via ArraysMethods.getAt(index) and the integer boxing und calculation. Ait recommended to change the following line

into


Obviously, this tackles the integer handling problem. After changing this line I ran the code again and had a look at the timings. The results are amazing. Here they are for sorting 100.000 and 1.000.000 integers:

n100.0001.000.000
Java1295
Scala1295
Groovy375041700
Groovy++ (old version)5154900
Groovy++ (new version)19130


This is marvellous! Now Groovy++ is really on a par with Java and Scala!


De-compiling the byte code again shows the difference. Here's the old byte code:

And here is the new version:

Still, there is no native array access, but the integer boxing is gone, it's primitive integer calculations.

Ait (Is that you, Alex?) will come up with a post with more details. I'll provide a link here then.


Update: These are the numbers for Java, Scala and Groovy with shifting instead of division. Only Groovy can take advantage of this:
n100.0001.000.000
Java1190
Scala1290
Groovy190022000
Groovy++ (new version)19130






Saturday, February 6, 2010

Groovy++ vs. Groovy vs. Java vs. Scala - Performance Update

I've been writing about a performance comparison between Java, Scala and Groovy in this and this post, where I compared the runtimes of these languages for a straight-forward (and far from idiomatic) implementation of the quicksort algorithm. As you might have heard, there's a new kid on the block: Groovy++ a.k.a. static Groovy. I was eager to see, how this would improve Groovy's results.

So, (without any further justification of this comparison) I took the same source code for Java, Scala and Groovy as previously and took this modified version of the Groovy code for Groovy++:


So, I basically took the Groovy code, and added the @Typed annotation and some more type information. I ran this on my machine with Java 1.6.0 Update 17, Scala 2.7.7, Groovy 1.7 and Groovy++ which is based on Groovy 1.8.0-SNAPSHOT. Here are the results (in ms) for sorting 100.000 and 1.000.000 integers:

n100.0001.000.000
Java1295
Scala1295
Groovy375041700
Groovy++5154900


Obviously, while still Java and Scala are by far the fastest, Groovy++ makes a huge difference. Groovy takes about 312x the time of Java/Scala, Groovy++ just takes 42x.

While there isn't much difference in the source code of Groovy and Groovy++, there is of course a big difference in the generated byte code. I had a look at it with the Java Decompiler. The Groovy byte code contains lots of dynamic dispatch code, while there's not much in the Groovy++ byte code that indicates that it was compiled from Groovy. Here's a short excerpt:


public Object quicksort(int[] a, int L, int R) {
while (true) {
int m = ArraysMethods.getAt(a, DefaultGroovyPPMethods.div(DefaultGroovyPPMethods.box(L + R), DefaultGroovyPPMethods.box(2)).intValue());
int i = L;
int j = R;
while (i <= j) {
for (; ArraysMethods.getAt(a, i) < m; (i++));
for (; ArraysMethods.getAt(a, j) > m; (j--));
if (i <= j) {
swap(a, i, j);
(i++);
(j--);
}
}
if (L < j) quicksort(a, L, j);
if (R <= i) break; R = R; L = i; a = a; this = this; } return null;
}


This isn't even far from the byte code generated by java. There is just that autoboxing of integers, integer division and the array access with getAt(). Considering the early state of Groovy++ this looks very promising.


Update: There's is a follow-up post that shows how to tune the Groovy++ code to make it run as fast as Java and Scala (Thanks to ait, see comments).