Lilienthal Lilienthal - 1 month ago 14
Java Question

Lambda expressions versus lambdaj

During a Java integration project I did last year I discovered lambdaj and was immediately convinced by its ability to let me produce more readable code faster. I remember reading about lambda expressions coming to 1.8 around that time as well and thinking that I had found a plugin that already brought me all that functionality.

Now I'm revisiting lambda expressions and see that I may have been mistaken on lambdaj's purpose and scope. The way I see it now, lambdaj doesn't really offer lambda expressions but is rather a domain specific language designed to replace repetitive loops on collections. Its DSL syntax was made to look similar to anonymous functions and provides some of the same functionality such as closures and curried functions, but in the end it's limited by the JLS.

I'm now wondering what 1.8's lambda expressions can bring to a Java project that lambdaj can't. Is it just a matter of increased performance with native support for anonymous functions? Will expressions similar to lambdaj's collection manipulation functions be present in 1.8? Or are the lambda expressions in 1.8 meant for me to create my own anonymous functions. In that case, should a specific version of lambdaj be made for 1.8 that recreates the function library using real anonymous functions?

Answer

lambdaj doesn't really offer lambda expressions

This is correct.

[lambdaj] provides some of the same functionality such as closures

If by this you mean "it provides closures"—no, it doesn't. A closure cannot exist without a lambda expression; it is actually a special case of a lambda expression, one which is the most demanding to implement.

Unfortunately, LambdaJ's project documentation is quite misleading in applying the term "closure" to something which doesn't qualify. An example from its Closures wiki page:

Closure println = closure(); { of(System.out).println(var(String.class)); }

The example is followed by this explanation:

In particular the var() method binds a free variable of type String to the closure.

That statement is simply false: there is no variable binding at all happening there, let alone a free variable. The construct results in something resembling a unary function, which expects a String argument. (Well, what it actually expects is an Object, but will fail at runtime if passed a non-String.)

On the other hand, the of() call in the example does go a bit in the direction of local variable capture. We might say that the argument passed to of() is captured by the object which it returns. However, we cannot refer to it in any further syntax; it is just the implicit target of the method call that follows. This is a far cry from full closures.

I'm wondering what 1.8's lambda expressions can bring to a Java project that lambdaj can't. Is it just a matter of increased performance with native support for anonymous functions?

Since LambdaJ doesn't provide the ability to write anonymous functions, the question is technically unanswerable. However, rest assured that Java 8's closures will outperform LambdaJ on a usecase-by-usecase basis because LambdaJ is fundamentally based on reflection, whereas Java's closures don't need it at all.

Will expressions similar to lambdaj's collection manipulation functions be present in 1.8?

Absolutely, and the support is very serious and complete. There are both more features, and the features are more composable. LamdaJ's capabilities are dwarfed by what is available out-of-the-box in Java 8. Check out the Streams API.

One of the primary design goals behind the Streams API was never even meant to be implemented by LambdaJ: the automatic parallelization of processing. Sure, FP-oriented collection processing looks nicer than the imperative idiom, but this is about much more than looks: it is a fundamental change. It is Java's bet on the future of computing, where the only way to boost performance will be to involve more parallel streams of processing.

Comments