Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java mechanisms at use in lambdaj closures

Lamdbaj allows the definition of closures in the Java language, various examples can be found here

My question is regarding the underlying Java mechanisms at use, for instance, to define the println closure, the following code is used:

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

This closure can be subsequently executed via:

println.apply("foobar");

I am curious as to what mechanisms in Java would allow the call to of(...).println(...) to become associated with the println instance itself.

Naturally, the lambdaj source code is available to read but I was hoping for a slightly higher level explanation if anyone has one. My reflection skills go as far as a bit of introspection and executing methods dynamically.

like image 904
Derek Mortimer Avatar asked Oct 23 '09 21:10

Derek Mortimer


2 Answers

I am Mario Fusco and I am the main developer of the lambdaj library.

First of all I would like to clarify something: lambdaj is not intended to replace any functional language. As I said last week in my speech at the Jug of Zurich if you have a chance to use Scala, go for it and never look back. Here you can find a resume of my speech where it is clearly stated that:

http://ctpjava.blogspot.com/2009/10/lambdaj-new-trends-in-java.html

I am an happy Scala developer too. But sometimes you are just obliged to develop in Java (in my experience, in the real world, about the 80% of times you cannot choose in which language you have to write your code) and in this case some of the lambdaj features could be helpful (or I hope so). I just wanted to bring to Java some functional features that are totally missing. Of course the result is not completely satisfying mainly due to the limitation imposed by Java itself.

As for the internal lambdaj mechanism, yes it uses a ThreadLocal in order to achieve that result. If you have other questions, curiosities or even better suggestions and constructive critics about lambdaj maybe you could be interested to register yourself to the lambdaj mailing list here:

http://groups.google.com/group/lambdaj

Bye Mario

like image 54
Mario Fusco Avatar answered Oct 22 '22 06:10

Mario Fusco


Well, of is presumably a static method which is imported statically so it can be called without the enclosing class name. I expect that var is the same. Both methods must return some type which have the methods subsequently called:

public class Printable {
  public void println(Var var);
}

public class Fac {
  public static Printable of(Object o) {
    return new Printable(o);
  }

  public static Var var(Class<?> clazz) {
    return new Var(clazz);
  }

} 

All of a sudden:

Fac.of(System.out).println(Fac.var(String.class));

Is valid Java. Using static imports, hey presto:

import static Fac.*;

of(System.out).println(var(String.class));

The curly-braces are obviously valid Java as you can add these in any method to aid in defining a lexical sope. This API-design style is called fluent and is best showcased by the JMock testing library.

By the way, if this is supposed to introduce closures to Java, it's quite ridiculous - the syntax is unreadably awful. Their I/O example actually made me laugh out loud. Try Scala!

EDIT - the two println calls are associated I believe because the first sequence of calls allow the library to capture the variables which you have passed in as parameters. These are probably captured in some ThreadLocal structure. When you then call a (also presumably static) println method, the library is using this captured data to actually execute the behaviour at a later point. Also testing related, the EasyMock test framework uses a similar mechanism (which uses Java proxies in the background) to capture expected values.

like image 2
oxbow_lakes Avatar answered Oct 22 '22 04:10

oxbow_lakes