Discussions

News: lambdaj 2.0 brings (almost) real closures to Java

  1. [Editor: Note that lambdaj will be featured as a breakout session at TheServerSide Java Symposium Europe, to be held in Prague on Oct 27-28. For more information, visit http://www.javasymposium.com .] Closures represent probably the most important feature that is missing in the tools box of each Java programmer. Some of them don't feel (or don't understand) the need of closures, while some other does and probably for this reason are evaluating to migrate toward a functional enabled programming language. The biggest part of us just learned to partially workaround this lack by using the verbose and poorly readable (anonymous) inner classes. Actually the opportunity to provide Java with this feature has been vastly debated and for a certain amount of time it seemed they were going to introduce it in Java 7 through the (in my opinion awful) BGGA specification. In the end they decided to give up with it leaving the Java developers still orphans of closures. lambdaj tries to partially fill this lack by introducing in its release 2.0 a new feature that allow to define, in its traditional DSL style, first-class functions with free variables like in the following example: Closure println = closure(); { of(System.out).println(var(String.class)); } I believe it is straightforward to understand what the println closure does. In particular the var() method binds a free variable of type String to the closure. Moreover, note that the curly brackets around the statement that define the behavior of the closure are only syntactic sugar and then could be safely removed even if I find the code more readable by keeping them. You can then invoke this closure by "closing" its free variable once: println.apply("one"); or more times: println.each("one", "two", "three"); As you can expect this last statement will cause the Strings "one", "two" and "three" to be printed on 3 different lines of the Java standard output. It is possible to create both untyped (as in the former example) and strongly typed closure. Supposing your classes has a method that sums 2 ints: public int sum(int a, int b) {   return a + b; } it is possible to instance a closure that invokes this method as it follows: Closure2 adder = closure(Integer.class, Integer.class); { of(this).sum(var(Integer.class), var(Integer.class)); } While you were allowed to call the first closure with any type and number of variables (it will eventually throw an Exception if invoked in a wrong way), you can invoke this second one only by passing 2 ints to it as expected: int result = (Integer)adder.apply(2, 3); Curry Another feature typically available on closures is the so called curry that allows to create another closure by fixing the value of some free variables. For example you can have a closure of one free argument that adds 10 to any number by doing a curry of the second variable of the former closure as it follows: Closure1 adderOf10 = adder.curry2(10); In this way by invoking this last closure with the value 3: int result = (Integer)adderOf10.apply(3); you will obtain 13 as expected. In the end, note that you could achieve exactly the same result by directly creating a closure with only one free parameter and the second one already fixed to 10 as in this last statement: Closure1 adderOf10 = closure(Integer.class, Integer.class); { of(this).sum(var(Integer.class), 10); } Why are closures useful? If you still don't see how closures can be useful for you, let me make a slightly more complex example that could show why I think that they are the most powerful tool in order to generalize your code and thus avoid duplications. At this purpose let's write a method that reads a file from the classpath and then prints its content line by line on the Java standard output: public void printFile(String fileName) {   BufferedReader reader = null;   try {     InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName);     reader = new BufferedReader(new InputStreamReader(stream));     for (String line = reader.readLine(); line != null; line = reader.readLine()) {       System.out.println(line); // This is actually the only meaningful statement in this method     }   } catch (IOException ioe) {     throw new RuntimeException("Error while reading file " + fileName, ioe);   } finally {     try {       if (reader != null) reader.close();     } catch (IOException ioe) {       throw new RuntimeException("Error while closing file reader", ioe);     }   } } There are lots of bloatware and maybe just one meaningful line of code in this method, isn't it? But now suppose you also need a method that write the file into a String and another one that just counts the number of non-empty lines in the file itself. Instead of copy and paste the former method other two times and change just a single statement in each new method, I think that could be a better idea to generalize it, by passing a closure that tells to the method, case by case, how a line read from the file should be managed, as it follows: public void printFile(String fileName) {   Closure1 lineReader = closure(String.class); { of(System.out).println(var(String.class)); }   readFileByLine(fileName, lineReader); } public String readFile(String fileName) {   StringWriter sw = new StringWriter();   Closure1 lineReader = closure(String.class); { of(sw).write(var(String.class)); }   readFileByLine(fileName, lineReader);   return sw.toString(); } public int countFileLines(String fileName) {   lineCounter = 0;   Closure1 lineReader = closure(String.class); { of(this).countNonEmptyLine(var(String.class)); }   readFileByLine(fileName, lineReader);   return lineCounter; } private int lineCounter = 0; void countNonEmptyLine(String line) {   if (line != null && line.trim().length() > 0) lineCounter++; } private void readFileByLine(String fileName, Closure1 lineReader) {   BufferedReader reader = null;   try {     InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName);     reader = new BufferedReader(new InputStreamReader(stream));     for (String line = reader.readLine(); line != null; line = reader.readLine()) {       lineReader.apply(line);     }   } catch (IOException ioe) {     throw new RuntimeException("Error while reading file " + fileName, ioe);   } finally {     try {       if (reader != null) reader.close();     } catch (IOException ioe) {       throw new RuntimeException("Error while closing file reader", ioe);     }   } }

    Threaded Messages (118)

  2. AS good as you can mimic closures[ Go to top ]

    In IMHO this is somewhat the best you can get out of Java in its current state if you want to mimic closures with the use of parameterized methods: mostly type safe, no inner classes (hence no final vars that would render a closure only useful in special cases). Nevertheless method AbstractClosure.closeOne(...) that evaluates a collection iteration closure in the end uses Reflection, which is perfomance-wise not optimal. You have to figure this out through decompilation, because the authors simply don't make any comment in the documentation how this works in the end ... For things to compile you would have to subclass class Lambda or write things in this way: Closure2 adder = Lambda.closure(Integer.class, Integer.class); { Lambda.of(this).sum(Lambda.var(Integer.class), Lambda.var(Integer.class)); } All right, it is not the fault of the authors that Java still has no extension methods like Objective-C for ages or C# for years, but this is still not very elegant. I prefer to wait for Sun/Oracle to implement real closures for us and extension methods.
  3. You have to figure this out through decompilation, because the authors simply don't make any comment in the documentation how this works in the end
    Why did you decompile it? To decompile an open-source project doesn't sound smart ... don't you think so? :)
    For things to compile you would have to subclass class Lambda or write things in this way:

    Closure2 adder = Lambda.closure(Integer.class, Integer.class); { Lambda.of(this).sum(Lambda.var(Integer.class), Lambda.var(Integer.class)); }
    You don't have to subclass anything (and actually you can't since Lambda is a final class). You should just declare a static import of it.
    All right, it is not the fault of the authors that Java still has no extension methods like Objective-C for ages or C# for years, but this is still not very elegant. I prefer to wait for Sun/Oracle to implement real closures for us and extension methods.
    I'm afraid you will wait for long long time then.
  4. Why did you decompile it? To decompile an open-source project doesn't sound smart ... don't you think so? :)
    I didn't find any sources on http://code.google.com/p/lambdaj/: the Sources tab is empty and all jars on the Download tab contain class files only.
    You don't have to subclass anything (and actually you can't since Lambda is a final class). You should just declare a static import of it.
    I see. Should have known that.
  5. I didn't find any sources on http://code.google.com/p/lambdaj/: the Sources tab is empty and all jars on the Download tab contain class files only.
    http://code.google.com/p/lambdaj/source/browse/#svn/trunk/src/main/java/ch/lambdaj
  6. Reflection - yeah it would be nice if you could tell us about the cost of Reflection here. The Interceptorxxx source file also says that it works with cglib. So, is bytecode generation automatic? I've always been very fond of Fluent and Closures for SQL - like .Net's LINQ. Cheers! Ashwin (http://www.ashwinjayaprakash.com).
  7. Couldn't Closure.apply() return a value of a type specified on closure creation or invocation? What about exceptions? Is it possible to declare exceptions that can be thrown by the closure?
  8. Couldn't Closure.apply() return a value of a type specified on closure creation or invocation?
    Well, I thought about it a lot while I was developing that part. In the end I decided to return just a generic Object from the closure invocation, because in my experience the biggest part of closure actually returns void and I didn't want to put too many generic types in the closure declaration. In other words, I preferred to use generics for the objects passed to the closure and not for the returned type, but this has been just my implementation choice, so if many people will express this need, I suppose it will be quite trivial to implement another closure having a typed return.
    What about exceptions? Is it possible to declare exceptions that can be thrown by the closure?
    No this is not possible, and to be honest I can't imagine how I could have implemented that. Anyway, as you can read in one of my former article, I don't like checked exceptions so I didn't care too much about them: http://www.theserverside.com/news/thread.tss?thread_id=55185
  9. You wrote "I believe it is straightforward to understand what the println closure does. In particular the var() method binds a free variable of type String to the closure." No, it binds a parameter. None of the examples in your post illustrate the use of free variables. Since free variables are a key part of the definition of closures, none of your examples are closures either.
  10. You wrote "I believe it is straightforward to understand what the println closure does. In particular the var() method binds a free variable of type String to the closure."

    No, it binds a parameter. None of the examples in your post illustrate the use of free variables. Since free variables are a key part of the definition of closures, none of your examples are closures either.
    Sorry, maybe I didn't explain myself very well. What I meant to say is that the var() methods is used to say that the closure has a free variable of the type passed to that method, while the value is actually bound to the closure by calling the apply() method on the closure itself. I hope is clearer now, even if I honestly believed that the examples I posted should be almost self-explanatory. Let me know if you still have some doubts or if I'm missing something. Thank you Mario
  11. What I meant to say is that the var() methods is used to say that the closure has a free variable of the type passed to that method, while the value is actually bound to the closure by calling the apply() method on the closure itself.
    That's certainly clear, but it is a misuse of terms. What you're describing is a parameter, not a free variable. The free variables of a closure are, by definition, bound when the closure is created (not when invoked). I don't know whether what you're describing is useful or not, or what to call it, but it certainly would not be correct to call it a closure.
  12. That's certainly clear, but it is a misuse of terms. What you're describing is a parameter, not a free variable. The free variables of a closure are, by definition, bound when the closure is created (not when invoked). I don't know whether what you're describing is useful or not, or what to call it, but it certainly would not be correct to call it a closure.
    Sorry, but I am really missing something now. Could you give me please a concrete example of a closure and in which part my implementation differs from it?
  13. Sorry, but I am really missing something now. Could you give me please a concrete example of a closure and in which part my implementation differs from it?
    Sure. Using BGGA syntax (and assuming an interface "Closure" is defined in scope): /** Return a closure that adds n to its argument */ Closure plus(int n) { // n is a free variable in this closure return { int x => x+n }; } Closure plus10 = plus(10); System.out.println(plus10.invoke(2)); // prints 12 The closure, above, references the free variable n that is defined outside the closure. None of your supposed closure examples use free variables (from their enclosing scope). What you have been calling a free variable is actually a parameter, like "x" in the example above.
  14. I can't understand the obsession behind phrases like "Java is going to die because closures are missing". A sort of closures is already in Java since v1.1, by the way thanks to Neal Gafter and others (am I wrong Neal?). public interface Closure { public Object invoke(Object n); } Closure plus(final int n) { Closure cl = new Closure() { public Object invoke(Object x) { return ((Integer)x) + n; } }; return cl; } Closure plus10 = plus(10); System.out.println(plus10.invoke(2)); // prints 12 Yeah, is not so compact than the "real" closure and but is enough for me and I using this kind of code again and again. I will welcome more compact closures in Java like BGGA proposal but they are not going to save the world, they are going to (very slightly) increase developer productivity and reduce the number of keyboards sold, no more. Something like traits would be more interesting in my Java based daily life. By the way, I would like in BGGA a syntax like: Closure plus(int n) { return int(x){x+n}; } "int x => x+n" sounds weird in Java, a proud descendent of the venerable C :)
  15. I can't understand the obsession behind phrases like "Java is going to die because closures are missing".

    A sort of closures is already in Java since v1.1, by the way thanks to Neal Gafter and others (am I wrong Neal?).
    Probably that's why lots of people refer to anonymous inner classes as the poor man's closure :)
    Yeah, is not so compact than the "real" closure and but is enough for me and I using this kind of code again and again.

    I will welcome more compact closures in Java like BGGA proposal
    It seems I am in good company when I say that I don't like the BGGA proposal: http://www.javac.info/bloch-closures-controversy.ppt Anyway of course I didn't feel the need to implement that feature if we could have had BGGA in Java 7. But since this is not the case, I don't understand why somebody presents as a viable alternative something that doesn't exist at all.
    but they are not going to save the world, they are going to (very slightly) increase developer productivity and reduce the number of keyboards sold, no more.
    Less (and more readable) code doesn't only save keyboards but mainly maintenance efforts. Stated that the biggest part of the cost of a software is in its maintenance part and not in its development one, I believe this advantage is not negligible.
  16. A "return" is missing: Closure plus(int n) { return int(x){return x+n}; } Anyway lambdaj is a interesting try.
  17. Using BGGA syntax (and assuming an interface "Closure" is defined in scope):


    /** Return a closure that adds n to its argument */
    Closure plus(int n) {
    // n is a free variable in this closure
    return { int x => x+n };
    }

    Closure plus10 = plus(10);
    System.out.println(plus10.invoke(2)); // prints 12


    The closure, above, references the free variable n that is defined outside the closure. None of your supposed closure examples use free variables (from their enclosing scope). What you have been calling a free variable is actually a parameter, like "x" in the example above.
    In which part your example differs from the following? Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); } System.out.println(plus10.apply(2)); // prints 12
  18. Using BGGA syntax (and assuming an interface "Closure" is defined in scope):


    /** Return a closure that adds n to its argument */
    Closure plus(int n) {
    // n is a free variable in this closure
    return { int x => x+n };
    }

    Closure plus10 = plus(10);
    System.out.println(plus10.invoke(2)); // prints 12


    The closure, above, references the free variable n that is defined outside the closure. None of your supposed closure examples use free variables (from their enclosing scope). What you have been calling a free variable is actually a parameter, like "x" in the example above.


    In which part your example differs from the following?

    Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); }
    System.out.println(plus10.apply(2)); // prints 12
    Mr. Gafter's example slightly rewritten: public static Closure plus10() { int start = 10; return { int x => x + start }; } public static void main(String[] env) { Closure p = plus10(); System.out.println(p.invoke(2)); // prints 12 } Now, do you see the difference? Kind regards, Stefan
  19. Binding a free variable[ Go to top ]

    Or, even more reduced: public static void main(String[] env) { int start = 10; Closure p = { int x => x + start }; System.out.println(p.invoke(2)); // prints 12 }

  20. public static Closure plus10() {

    int start = 10;

    return { int x => x + start };
    }


    public static void main(String[] env) {

    Closure p = plus10();

    System.out.println(p.invoke(2)); // prints 12
    }


    Now, do you see the difference?

    Kind regards,
    Stefan
    I could rewrite my example accordingly to your modifications and still not seeing any difference: public static class Adder() {   int start = 10;   public int plus10(int x) {     return x + start;   } } public static void main(String[] env) {   Closure p = closure(); { of(new Adder()).plus10(var(Integer.class)); }   System.out.println(p.apply(2)); // prints 12 }
  21. I could rewrite my example accordingly to your modifications and still not seeing any difference:


    public static class Adder() {
      int start = 10;
      public int plus10(int x) {
        return x + start;
      }
    }

    public static void main(String[] env) {
      Closure p = closure(); { of(new Adder()).plus10(var(Integer.class)); }
      System.out.println(p.apply(2)); // prints 12
    }
    In your example, you don't have a free variable. That's the difference. int start = 10; // closure gets constructed and captures the free variable "start" from the enclosing scope Closure p = { int x => x + start }; Mr. Gafter's point was that you don't have any free variable that gets captured at the closure's construction. So, technically, it is not a closure.
    The free variables of a closure are, by definition, bound when the closure is created (not when invoked).
  22. I could rewrite my example accordingly to your modifications and still not seeing any difference:


    public static class Adder() {
      int start = 10;
      public int plus10(int x) {
        return x + start;
      }
    }

    public static void main(String[] env) {
      Closure p = closure(); { of(new Adder()).plus10(var(Integer.class)); }
      System.out.println(p.apply(2)); // prints 12
    }


    In your example, you don't have a free variable. That's the difference.


    int start = 10;

    // closure gets constructed and captures the free variable "start" from the enclosing scope

    Closure p = { int x => x + start };



    Mr. Gafter's point was that you don't have any free variable that gets captured at the closure's construction. So, technically, it is not a closure.


    The free variables of a closure are, by definition, bound when the closure is created (not when invoked).
    The enclosing scope of the closure in my example is the instance of the Adder class and it is captured when the closure is defined through the of() method.
  23. Scope[ Go to top ]

    The enclosing scope of the closure in my example is the instance of the Adder class ...
    IMO, that appears to be a quite innovative (re-)definition of lexical scope. But anyhow, maybe you're not so wrong after all. I can already see, how you would do the following with your Adder class. int start = 10; System.out.println({ int x => x + start }.invoke(2)); // prints 12 start = 12; System.out.println({ int x => x + start }.invoke(2)); // prints 14
  24. params being declared final[ Go to top ]

    Now, do you see the difference?

    Kind regards,
    Stefan
    To be really really honest, I don't see the difference, either. Anyhow, the point of a closure is that you put into the closure expression body what has no potential for re-use, such as "x + start" or "x < 3" as in #{ 1, 2, 3} select: [ :x | x < 3 ] (Smalltalk syntax here). What is re-usale is in the select: method. The boolean expression "x { public T evaluate(T parameter); } public class BlockTest { public static void main(String[] args) { BlockTest test = new BlockTest(); Block block = test.plus(10); int result = block.evaluate(2); System.out.println(result); // ==> 12 } public Block plus(final int n) { return new Block() { public Integer evaluate(Integer arg) { return arg + n; } }; } } It's a little verbose, but still readable. What I'm not sure about is whether n being declared final creates a substantial limitation or not compared to a closure where n would not need to be declared final. If I do this in Smalltalk | block n | n := 10. block := [ :x | x + n ]. n = 12. block value: 2. it also returns 12 and not 14. I'd be happy if someone could shed some light the problem with n having to be declared final.
  25. In which part your example differs from the following?

    Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); }
    System.out.println(plus10.apply(2)); // prints 12
    It differs in the part where the thing being added (10) is a variable, not a constant, so it can differ from closure to closure even though those closures are created by the same closure expression. In your code the number 10 is written inline, so the closure expression you've written can only be used to add 10.
  26. In which part your example differs from the following?

    Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); }
    System.out.println(plus10.apply(2)); // prints 12


    It differs in the part where the thing being added (10) is a variable, not a constant, so it can differ from closure to closure even though those closures are created by the same closure expression. In your code the number 10 is written inline, so the closure expression you've written can only be used to add 10.
    In the same way you write: Closure plus10 = plus(10); to have a closures that adds 10 and Closure plus12 = plus(12); to have another closure that adds 12, i write respectively Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); and Closure1 plus12 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 12); I admit my syntax is more verbose and inelegant, but it is hard to achieve something better in plain Java, and anyway the result is exactly the same.
  27. In the same way you write:

    Closure plus10 = plus(10);

    to have a closures that adds 10 and

    Closure plus12 = plus(12);

    to have another closure that adds 12, i write respectively

    Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10);

    and

    Closure1 plus12 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 12);

    I admit my syntax is more verbose and inelegant, but it is hard to achieve something better in plain Java, and anyway the result is exactly the same.
    You've demonstrated in this particular case that that you can't write a method like the one I've written, but you can instead inline it into each of its call sites. More complex methods using closures can be inlined (copy-and-pasted) using your technique too, but the point of introducing methods (including those with closures) is to avoid duplicating code. If you have examples of expressions using closures that can't be abstracted out as methods, you've demonstrated a limitation of what you've been calling closures. In this case, the limitation is that they aren't actually closures because they can't close over variables from the enclosing scope.
  28. In the same way you write:

    Closure plus10 = plus(10);

    to have a closures that adds 10 and

    Closure plus12 = plus(12);

    to have another closure that adds 12, i write respectively

    Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10);

    and

    Closure1 plus12 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 12);

    I admit my syntax is more verbose and inelegant, but it is hard to achieve something better in plain Java, and anyway the result is exactly the same.


    You've demonstrated in this particular case that that you can't write a method like the one I've written, but you can instead inline it into each of its call sites. More complex methods using closures can be inlined (copy-and-pasted) using your technique too, but the point of introducing methods (including those with closures) is to avoid duplicating code. If you have examples of expressions using closures that can't be abstracted out as methods, you've demonstrated a limitation of what you've been calling closures. In this case, the limitation is that they aren't actually closures because they can't close over variables from the enclosing scope.
    I suppose I can achieve the same result using the curry feature. Somebody pointed out that probably partial evaluation is a more correct name, but anyway it works in the following way: having defined Closure2 plus = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), var(Integer.class)); you can have: Closure1 plus10 = plus.curry2(10); and Closure1 plus12 = plus.curry2(12); Is that closer to what you were asking?
  29. I suppose I can achieve the same result using the curry feature. Somebody pointed out that probably partial evaluation is a more correct name, but anyway it works in the following way: having defined

    Closure2 plus = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), var(Integer.class));

    you can have:

    Closure1 plus10 = plus.curry2(10);

    and

    Closure1 plus12 = plus.curry2(12);

    Is that closer to what you were asking?
    That binds to a constant, not a variable. The point is to use an identifier in the body of the lambda expression, and have that bound to a lexically enclosing variable. That is one of the defining features of closures, and the facility you describe lacks it.
  30. That binds to a constant, not a variable. The point is to use an identifier in the body of the lambda expression, and have that bound to a lexically enclosing variable. That is one of the defining features of closures, and the facility you describe lacks it.
    This is only a trivial detail and under a practical point of view there isn't anything you cannot do with my implementation. Or at least I cannot find it. Anyway, as I wrote in one of my former post, you have even that possibility by defining the closure as it follows: public static class Adder() {   int start = 10;   public int plus10(int x) {     return x + start;   } } public static void main(String[] env) {   Closure p = closure(); { of(new Adder()).plus10(var(Integer.class)); }   System.out.println(p.apply(2)); // prints 12 } In this case the start variable of the Adder instance is the identifier bound to a lexically enclosing variable you were missing.
  31. This is only a trivial detail and under a practical point of view there isn't anything you cannot do with my implementation. Or at least I cannot find it. Anyway, as I wrote in one of my former post, you have even that possibility by defining the closure as it follows:

    public static class Adder() {
      int start = 10;
      public int plus10(int x) {
        return x + start;
      }
    }

    public static void main(String[] env) {
      Closure p = closure(); { of(new Adder()).plus10(var(Integer.class)); }
      System.out.println(p.apply(2)); // prints 12
    }

    In this case the start variable of the Adder instance is the identifier bound to a lexically enclosing variable you were missing.
    For what it's worth, I doubt that the "start" variable qualifies as being in the lexical scope of the block where you create your lambdaj closure (the main method). What would you do if you needed a plusN(int n) function as in Mr. Gafter's original example? Creating new Adder instances and then create new "closures" that capture those distinct instances, I suppose? Technically, this is not what a closure is. Closure means "binding a function to its scope", and, if the values (variables) in its scope change you don't have to "rebind" the function (or recreate the closure) to pick up those changes. But, anyhow, as you say, that can be seen as a trivial (?) technical detail. Maybe we'd need a more compelling (practically convincing) example to further discuss the merits of the lambaj approach vs. closures as defined in CS. What do you think? Kind regards, Stefan
  32. Maybe we'd need a more compelling (practically convincing) example to further discuss the merits of the lambdaj approach vs. closures as defined in CS. What do you think?
    This is exactly what I asked to mr. Gafter, since I cannot find it by myself: a practical example where an implementation of this traditional closure definition (and I doubt that BGGA completely adheres to it for other reasons) do something that the lambdaj implementation cannot do. Can you find it? Thank you Mario
  33. This is exactly what I asked to mr. Gafter, since I cannot find it by myself: a practical example where an implementation of this traditional closure definition (and I doubt that BGGA completely adheres to it for other reasons) do something that the lambdaj implementation cannot do. Can you find it?

    Thank you
    Mario
    Maybe, I'm not sure ;) Actually, in my day-to-day work as a programmer, I'd be quite happy with Java's anonymous inner classes aside from the fact that they require so much code cruft on the call side. That often prevents me from designing a nice functional API because it would put too much burden on my clients. As a matter of fact, the "final" restriction for anonymous classes almost never hits me, and I'm deeply sceptical whether communicating state through mutable variables captured by more than one closure (in the same scope) would be a defendable idea. So this, for example, is a "general" closure feature I've never wanted to use in practical work (until now). In that respect, what BGGA gives me (amongst other, cooler features) is for example a simple syntax to avoid the call side cruft that I can use in a standard JRE 6 without imposing any -Xbootclasspath hacks on the client (due to BGGA's closure conversion). There would be more things to discuss, but I have to go to bed now - tomorrow's work is waiting ;) Cheers, Stefan
  34. Let's go friends[ Go to top ]

    As a matter of fact, the "final" restriction for anonymous classes almost never hits me,
    Maybe just make anonymous inner classes less verbose and that's good enough.
    There would be more things to discuss, but I have to go to bed now - tomorrow's work is waiting ;)
    There's been quite a bit of time of silence here in the meanwhile. I think even Mr.Fusco must have gone to bed, at least for a short while. And I will do the same thing now. Let's see tomorrow what the guys from the US have written in the meanwhile ...
  35. Re: Let's go friends[ Go to top ]

    As a matter of fact, the "final" restriction for anonymous classes almost never hits me,
    Maybe just make anonymous inner classes less verbose and that's good enough.
    I agree. If anonymous inner classes were less verbose and more readable I suppose I didn't feel the need to implement that feature (now I have finally understood why I couldn't call it closure). I was just tired to wait some functional programming features from the Sun/Oracle "experts" and tried to implement something similar by myself. In one word since I felt I was missing a tool I tried to build it by myself and since I am already using it effectively I decided to share it with the Java community.
    There would be more things to discuss, but I have to go to bed now - tomorrow's work is waiting ;)
    There's been quite a bit of time of silence here in the meanwhile. I think even Mr.Fusco must have gone to bed, at least for a short while. And I will do the same thing now. Let's see tomorrow what the guys from the US have written in the meanwhile ...
    Yes I must go to sleep as well. In the meanwhile thank you for explaining me which part of the closure definition I was missing.
  36. Re: Let's go friends[ Go to top ]

    Maybe just make anonymous inner classes less verbose and that's good enough.
    You're right. For the usual 08-15 programming tasks and even most of the FP oriented APIs that would suffice. BGGA, of course, has a broader scope (user-defined control abstractions) which is cool but not strictly necessary for "getting the job done".
  37. Re: Let's go friends[ Go to top ]

    I don't think annonymous inner classes are too verbose. Everything you need to read to understand the code is right there. If you remove the "boilerplate" you lose indications of what is going on.
  38. Re: Let's go friends[ Go to top ]

    I don't think annonymous inner classes are too verbose. Everything you need to read to understand the code is right there. If you remove the "boilerplate" you lose indications of what is going on.
    "A closure is a combination of a >functionclass { public T evaluate(T parameter); } public class BlockTest { public Block plus(final int n) { return new Block() { public Integer evaluate(Integer arg) { return arg + n; } }; } public static void main(String[] args) { BlockTest test = new BlockTest(); Block block = test.plus(10); int result = block.evaluate(2); System.out.println(result); // ==> 12 } } And that is a little bit verbose compared to Closure plus(int n) { return { int x => x+n }; } Closure plus10 = plus(10); System.out.println(plus10.invoke(2)); // prints 12 Wished I could figure out how to get indention to work here ...
  39. Re: Let's go friends[ Go to top ]

    "A closure is a combination of a >functionclass<. You unnecessarily have to define the whole anonymous inner class and then the function representing the closure.</blockquote> I was talking about removing some parts of the code like the "new" keyword and the method declaration of the anonymous inner class as suggested by those who want only a simplification of the syntax. Adding real closures to java is more negative than positive because there is very little places we'd need them in web applications which is the most common type of application developed in java. Besides, passing a block of code instead of a normal object around is very different from what java as a Object-Oriented language aims.
  40. Re: Let's go friends[ Go to top ]

    Adding real closures to java is more negative than positive because there is very little places we'd need them in web applications which is the most common type of application developed in java.
    This is a common but surprising assumption I am reading on some posts in these days: "I develop web application" --> "web applications are the most common type of application developed in java" "I don't like functional programming" --> "all the developers don't want functional features in java" "I don't know how to use closure or first-class function" --> "the whole world doesn't feel the need of closures" Assuming that everybody develop the same things and have the same needs is a very nasty form of presumption.
    Besides, passing a block of code instead of a normal object around is very different from what java as a Object-Oriented language aims.
    IMHO there are languages like Scala that prove that object orientation and functional programming can be mixed in a very effective way.
  41. Re: Let's go friends[ Go to top ]

    Assuming that everybody develop the same things and have the same needs is a very nasty form of presumption.
    It's not about the same needs, it is about what is more useful for the majority of users.
    IMHO there are languages like Scala that prove that object orientation and functional programming can be mixed in a very effective way.
    They can be mixed but they are different ways of writing the same thing, you aren't adding anything new.
  42. Re: Let's go friends[ Go to top ]

    it is about what is more useful for the majority of users.
    And do you believe to know what is more useful for the majority of users? I feel happy when I discover what is more useful for me and my team :)
  43. Re: Let's go friends[ Go to top ]

    And do you believe to know what is more useful for the majority of users?
    I feel happy when I discover what is more useful for me and my team :)
    We need to evaluate language changes in some context, I think web applications are a reasonable context given we are on TheServerSide.com. Many people here deal with web applications. I think someone with more experience with Grails for example could give us more concrete examples of uses for closures in web apps.
  44. Re: Let's go friends[ Go to top ]

    IMHO there are languages like Scala that prove that object orientation and functional programming can be mixed in a very effective way.

    They can be mixed but they are different ways of writing the same thing, you aren't adding anything new.
    I doubt that. Scala would be a very different language without functional concepts like pattern matching applied to Objects (deconstruction). Also, Scalas focus on object immutability and the actor aproach to concurrency clearly stem from its functional parent.
  45. free variable?[ Go to top ]

    Isn't a "free variable" a way to introduce side-effects to a function? How does that relate to functional programming principles? Isn't the inner-class final "limitation" actually producing stateless functions? If however a best-practice exists where closures should minimise use of "free variables" then what is the big issue with lambdaj?
  46. Re: free variable?[ Go to top ]

    Also, is the need to deal with the inner-class final "limitation" what drives the alternative closure efforts? Wouldn't we be better off in this case by altering javac?
  47. Re: free variable?[ Go to top ]

    Also, is the need to deal with the inner-class final "limitation" what drives the alternative closure efforts?
    Not really, because you can get around that limitation by replacing the final variable with an array of length 1. The array is final then, but not its contents which you can change without a problem. I would say the main problem is that closures a very concise whereas anonymous inner classes create code bloat. Then there are problems with returning from an inner class (return, break, continue don't work as expected). For an example see http://gafter.blogspot.com/2006/08/whats-point-of-closures.html
    If however a best-practice exists where closures should minimise use of "free variables" then what is the big issue with lambdaj?
    The way I understand it the point is that with the use of a free variable you see state of the closure's surrounding environment at the time the closure is evaluated and not at the time when the closure was created. Otherwise you would mess around with meanwhile outdated data.
    Isn't a "free variable" a way to introduce side-effects to a function?
    Long time ago I had a Scheme class. Side effects were taught to be a wanted feature which confused the shit out of me. I still don't know what they mean by "programming with side effects".
  48. Re: free variable?[ Go to top ]

    I would say the main problem is that closures a very concise whereas anonymous inner classes create code bloat. Then there are problems with returning from an inner class (return, break, continue don't work as expected). For an example see http://gafter.blogspot.com/2006/08/whats-point-of-closures.html
    I read that and other posts on Mr. Gafter blog and I just have 2 very practical consideration: 1. The problem proposed in that post can be far easily resolved by using lambdaj features in few lines of code, in a more readable and maintainable way and without writing a single loop or closure. 2. After I have browsed and read almost all the entries regarding closure in his blog I still haven't found a problem that cannot be resolved by using the closure feature implemented in lambdaj.
  49. Re: free variable?[ Go to top ]

    I still haven't found a problem that cannot be resolved by using the closure feature implemented in lambdaj.
    Yes, this fact is a generalization of the Church-Turing thesis. I'll also note that these problems can also be "resolved" in assembly language. And yet we continue to develop high-level programming languages and use them instead of assembly language. The point of adding closures is not to make things computable that were not computable before. Rather it is to increase the level of abstraction in the programmer's toolset, thereby reducing the "accidental complexity" of programs written in the language. Examples of the kinds of benefits are a reduced need for boilerplate (or copy-and-paste code), and programs that are easier to read (and write). Have you seen the video?: http://video.google.com/videoplay?docid=4051253555018153503
  50. Re: free variable?[ Go to top ]

    The point of adding closures is not to make things computable that were not computable before. Rather it is to increase the level of abstraction in the programmer's toolset, thereby reducing the "accidental complexity" of programs written in the language. Examples of the kinds of benefits are a reduced need for boilerplate (or copy-and-paste code), and programs that are easier to read (and write).
    Exactly. Has anyone ever looked at the source code of the Functional Java ( http://functionaljava.org/ ) project? It is a real mess. For example, look at the code of the method public static F>>>>>>> curry(F8 f) in the class "fj.Function" It is a work of art: 8 levels of nested anonymous classes! Not many programmers can bear up with this programming style for a prolonged time. And this is one of the reasons (not the only one) why these FP-style APIs are not very popular in Java. It's simply impractical now. With something like BGGA this can be written in one line of code and it will be way more readble afterwards. Not to speak of the ease of use that you would have for the call site of such an API!
  51. Re: free variable?[ Go to top ]

    >Exactly.

    Has anyone ever looked at the source code of the Functional Java ( http://functionaljava.org/ ) project? It is a real mess.


    For example, look at the code of the method


    public static F>>>>>>> curry(F8 f)


    in the class "fj.Function"


    It is a work of art: 8 levels of nested anonymous classes! Not many programmers can bear up with this programming style for a prolonged time. And this is one of the reasons (not the only one) why these FP-style APIs are not very popular in Java. It's simply impractical now.
    That's why I started writing lambdaj. I am sure you cannot find anything similar in it.
    With something like BGGA this can be written in one line of code and it will be way more readble afterwards. Not to speak of the ease of use that you would have for the call site of such an API!
    I suppose you mean something easy to be managed like that: static Pair<{ => int },{ int => }> joinedCounters(int initial) {   return Pair.<{ => int },{ int => }>of(     { => intial++ }, { => intial++ }); } Really readable indeed. This piece of code has been copied from the Bloch's presentation who in turn took it from test code that ships with the BGGA prototype.
  52. Re: free variable?[ Go to top ]

    I suppose you mean something easy to be managed like that:


    static Pair<{ => int },{ int => }> joinedCounters(int initial) {
      return Pair.<{ => int },{ int => }>of(
        { => intial++ }, { => intial++ });
    }


    Really readable indeed. This piece of code has been copied from the Bloch's presentation who in turn took it from test code that ships with the BGGA prototype.
    Hhm, is it that hard to read? Without looking it up in the Bloch presentation and even without seeing the source of "of()" I find it pretty easy to understand.
  53. Re: free variable?[ Go to top ]

    static Pair<{ => int },{ int => }> joinedCounters(int initial) { return Pair.<{ => int },{ int => }>of( { => intial++ }, { => intial++ }); }
    What's the point in the => symbol when the closure has no variable? Should be allowed to leave it away, then.
  54. Re: free variable?[ Go to top ]

    static Pair<{ => int },{ int => }> joinedCounters(int initial) {
    return Pair.<{ => int },{ int => }>of(
    { => intial++ }, { => intial++ });
    }

    What's the point in the => symbol when the closure has no variable? Should be allowed to leave it away, then.
    The type of the return value?
  55. Re: free variable?[ Go to top ]

    The type of the return value?
    To clarify: what would you write in the case of a pure side effect, as e.g. (in C notation): void doSomething(void) In BGGA this is "{ => }" Your proposal would amount to "{}" I'm no parser expert, not sure if that would really complicate the grammar or if there are other issues lurking around that I'm not aware of.
  56. Re: free variable?[ Go to top ]


    static Pair<{ => int },{ int => }> joinedCounters(int initial) {
      return Pair.<{ => int },{ int => }>of(
        { => intial++ }, { => intial++ });
    }
    You (or Joshua Bloch) seems to have the type parameter wrong, btw. I think it should be <{ => int },{ => int}> not <{ => int },{ int => }>
  57. Re: free variable?[ Go to top ]

    You could also write this in a more traditional style if you desire so. public interface Func { R invoke(); } static Pair, Func> joinedCounters(int initial) { return Pair., Func>of( { => intial++ }, { => intial++ }); } But, honestly, I like the function types better (and they are more general).
  58. Re: free variable?[ Go to top ]

    This site somehow likes to balance the angle brackets, so it inserts a wrong closing angle after the Pair<Func </code>
  59. Re: free variable?[ Go to top ]

    You could also write this in a more traditional style if you desire so.
    Not that this API is particularly illustrative (it was intended as a test in a suite, not a recommended use), but you can write something that has the same behavior without any language extensions at all: class JoinedCounters { private int counter; private JoinedCounters(int initial) { this.counter = initial; } private class Counter implements Func { public Integer invoke() { return counter++; } } static Pair, Func> joinedCounters(int initial) { JoinedCounters outer = new JoinedCounters(initial); return new Pair,Func>( outer.new Counter(), outer.new Counter()); } }
  60. Re: free variable?[ Go to top ]

    You could also write this in a more traditional style if you desire so.


    Not that this API is particularly illustrative (it was intended as a test in a suite, not a recommended use), but you can write something that has the same behavior without any language extensions at all:


    class JoinedCounters {
    private int counter;
    private JoinedCounters(int initial) {
    this.counter = initial;
    }
    private class Counter implements Func {
    public Integer invoke() {
    return counter++;
    }
    }
    static Pair, Func> joinedCounters(int initial) {
    JoinedCounters outer = new JoinedCounters(initial);
    return new Pair,Func>(
    outer.new Counter(), outer.new Counter());
    }
    }
    Sure that is the same. Maybe we could do something different. Mr. Fusco could show us the Scala translation of the original BGGA snippet. I doubt that it would look significantly more "readable". Even the C# 3.0 translation almost looks the same as BBGA.
  61. Re: free variable?[ Go to top ]

    That's why I started writing lambdaj. I am sure you cannot find anything similar in it.
    You make me curious. Perhaps I'll have the time look into it over this weekend. But, let's face it, the examples you've presented here for the call site don't look very promising (for my liking, at least). Kind regards, Stefan
  62. Readability[ Go to top ]

    Really readable indeed. This piece of code has been copied from the Bloch's presentation who in turn took it from test code that ships with the BGGA prototype.
    I reread Mr. Bloch's presentation today and I now think that slide 30 ("Function types are hard to read") from which you took this example is a completely made-up story. I have an older download of the BGGA prototype (May 2008, I think) that still contains this test code (96 files overall). I've never looked at that code before, but today I did. It seems, Mr. Bloch has purposely choosen the oddest examples he could find to drive his point home. It's not at all representative of the code in general (and, keep in mind, it's compiler test code, not the kind of code a library writer or application programmer would write). It's funny that, of the 3 examples on slide 30, you've chosen the only one that (at least) I'm not having a problem with ;) And, in passing, the next slide (31, "Function types encourage an exotic programming style") is completely laughable for anyone who has learned a functional programming language.
  63. Re: Readability[ Go to top ]

    It's funny that, of the 3 examples on slide 30, you've chosen the only one that (at least) I'm not having a problem with ;)
    I had to copy it by hand from the video presentation because somebody removed the PowerPoint presentation, so I just took the shortest of the 3. On a separate note, if BGGA was so readable and well designed, could somebody explain me why we won't have it in Java 7?
  64. Re: Readability[ Go to top ]

    It's funny that, of the 3 examples on slide 30, you've chosen the only one that (at least) I'm not having a problem with ;)

    I had to copy it by hand from the video presentation because somebody removed the PowerPoint presentation, so I just took the shortest of the 3.
    The third example is even a bit shorter. I cand send you the PowerPoint if you want. Just drop me a line at forename dot surnmame at googlemail dot com
    On a separate note, if BGGA was so readable and well designed, could somebody explain me why we won't have it in Java 7?
    Good question, I don't know the answer. There certainly is some feeling of unease in the Java community at further changes to the Java language after the perceived Generics "debacle" (wich it isn't, in my judgement). BGGA was not the only closures proposal, though the most principled one to my mind. This article http://www.javaworld.com/javaworld/jw-06-2008/jw-06-closures.html?page=1 gives a good overview of the different approaches. BGGA was the most "visible" of these, so it received the most attention. Joshua Bloch's presentation was certainly enough for most Java programmers to decline it from the outset. I remember being fairly alarmed after reading it in Jan. 2008. But how many programmers took the time to work through Zdenĕk Troníček's closures tutorial that is linked from www.javac.info ? If they did that, they might have come to the conclusion that it is no big deal at all. Even PHP and VB do have closures now, and I haven't heard of a single VB programmer to be contemplating suicide on that account. I don't believe that the concept of closures is too hard for the average Java programmer (given the fact that all other languages have this concept now). I'm programming in Java for 9 years now and the only significant innovation of the language in that time has been the introduction of Generics. I feel grief when I look at the state of the language. Looks like Java is in maintenance mode now and we are today's COBOL programmers. Anyway, rant mode off now. You said in your introduction that you find the BGGA spec "awful". Your position may be very well-grounded or it may be not. I cannot know that. But I know that a lot of people that are saying things like this don't know very much about the topic they are talking about. Btw, don't you find it funny that Mr. Bloch seems to recommend to leave Java as it is and use Scala instead (slide 62)? I wish you the best of luck for your presentation at Prague. Cheers, Stefan
  65. Re: Readability[ Go to top ]

    Good question, I don't know the answer. There certainly is some feeling of unease in the Java community at further changes to the Java language after the perceived Generics "debacle" (wich it isn't, in my judgement).
    I like generics. As you can see I made a huge use of them in lambdaj and I do the same in the biggest part of the code I write. That said, sometimes I still find myself in a warning mess and even worse I believe their lack of reification at runtime is very limitating.
    BGGA was not the only closures proposal, though the most principled one to my mind. This article http://www.javaworld.com/javaworld/jw-06-2008/jw-06-closures.html?page=1 gives a good overview of the different approaches.

    BGGA was the most "visible" of these, so it received the most attention.
    I knew the other 2 proposals but I focused my attention on BGGA (as the biggest part of the other Java programmers interested in this topic) just because it seemed the most probable choice.
    I feel grief when I look at the state of the language. Looks like Java is in maintenance mode now and we are today's COBOL programmers.
    I have the same feeling. I am not a fan of the BGGA spec, but I'd preferred to have it instead of not having closure at all, as much as I prefer to have generics with their defects instead of not having them at all,
    You said in your introduction that you find the BGGA spec "awful". Your position may be very well-grounded or it may be not. I cannot know that. But I know that a lot of people that are saying things like this don't know very much about the topic they are talking about.
    As I said I don't particularly like the BGGA syntax but I suppose I could deal with it. What I found truly awful, confusing and error-prone in the BGGA spec is the non-local return (break and continue) feature. I tried to understand the reasons behind this choice but honestly I couldn't. A closure invocation should be the same of another normal method one, so I don't understand why that particular invocation should change the flow control of the invoker. Of course I don't know all the languages supporting closure, but none of the ones I know work in this way.
    Btw, don't you find it funny that Mr. Bloch seems to recommend to leave Java as it is and use Scala instead (slide 62)?
    As you said Java seems to be in maintenance mode and remaining so it is destined to become the COBOL of our age. I know the biggest part of the Java programmers don't agree with me, but as I wrote in one of my former articles ( http://www.theserverside.com/news/thread.tss?thread_id=55185 ) Java has some important lacks and issues and I am quite tired to deal with them. And to resolve these problems definitively I see only one solution: drop the backward compatibility with the older Java versions. I am quite sure that this won't happen but I am far more sure that I don't want to become a COBOL programmer of the 21st century.
    I wish you the best of luck for your presentation at Prague.

    Cheers,
    Stefan
    Thanks a lot Stefan It will be great if you could send me the Bloch presentation to mario.fusco[at]gmail.com. It would be even greater if we could continue this discussion privately and if I could ask your advices for the next lambdaj releases. Thanks again Mario
  66. Re: Readability[ Go to top ]

    What I found truly awful, confusing and error-prone in the BGGA spec is the non-local return (break and continue) feature. I tried to understand the reasons behind this choice but honestly I couldn't. A closure invocation should be the same of another normal method one, so I don't understand why that particular invocation should change the flow control of the invoker. Of course I don't know all the languages supporting closure, but none of the ones I know work in this way.
    You've seen the video and still don't understand? There are a number of languages that work this way, including Ruby and Scala. I highly recommend learning something about them.
  67. Re: Readability[ Go to top ]

    You've seen the video and still don't understand? There are a number of languages that work this way, including Ruby and Scala. I highly recommend learning something about them.
    True, BGGA follows the Scala model. But I'm really unsure myself now. I've never seen any usage of non-local return in Scala code. The only examples I could come up with are fairly contrived, like the following one: case class Person(age : Int) object Main {   val persons = List(new Person(35), new Person(20),                      new Person(18), new Person(7))   private def havePersonsOlderThan(ageMin : Int) : Boolean = {       // deliberately choosen foreach to be reminiscent of       // a Java for loop that is terminated prematurely when the predicate holds       persons.foreach( p => {           println(p)           if ( p.age > ageMin ) return true         }       )       false   }   def main (args : Array[String] ) = {       println(havePersonsOlderThan(20))   } } In that example the "return" is obviously needed. I've always thought non-local return is necessary for control abstractions, but I'm now unable to come up with an example that I find convincing. Could you please give me a pointer to one of your control abstraction examples where non-local return is actually used? I also have your "Closures Cookbook" presentation, so yould could also take an example from there. Thanks, Stefan
  68. Re: Readability[ Go to top ]

    I've always thought non-local return is necessary for control abstractions, but I'm now unable to come up with an example that I find convincing. Could you please give me a pointer to one of your control abstraction examples where non-local return is actually used?
    See http://gafter.blogspot.com/2007/03/closures-for-organizing-your-code.html
  69. Re: Readability[ Go to top ]

    See http://gafter.blogspot.com/2007/03/closures-for-organizing-your-code.html
    I see, thanks. This is a clever use case. I think I could have employed this technique myself a few times. Nevertheless, I would expect that in Java programming it would come up as infrequently as it seems to do in Scala. So it is good to have this in your toolbox but it is maybe not so important as closures per se.
  70. Re: free variable?[ Go to top ]

    Have you seen the video?: http://video.google.com/videoplay?docid=4051253555018153503
    It very, very good. Highly recommended.
  71. Re: free variable?[ Go to top ]

    Have you seen the video?: http://video.google.com/videoplay?docid=4051253555018153503
    I've finally found the time the watch your presentation. Very interesting, thanks a lot. Of course I didn't want to compare my small library with the BGGA specification. I was stupid if that was my intention. They are on 2 different levels of complexity and richness. But the fact here it is that we don't have closures in Java 6 and we won't have them neither in Java 7. So I just tried to partially fill this lack. Said that, in some simple cases, I can do things with my library in a way quite similar to what you showed in your presentation. Let me make a small example. Having defined the method withLock() as it follows: private void withLock(Lock lock) {   Closure c = closure();   try {     lock.lock();     c.apply();   } finally {     lock.unlock();   } } if you have a doSomething() method: public void doSomething() {   // do something here ... } you can invoke this method while holding the lock as it follows: withLock(lock); {   of(this).doSomething(); }
  72. Re: free variable?[ Go to top ]

    Having defined the method withLock() as it follows:


    private void withLock(Lock lock) {
      Closure c = closure();
      try {
        lock.lock();
        c.apply();
      } finally {
        lock.unlock();
      }
    }


    if you have a doSomething() method:


    public void doSomething() {
      // do something here ...
    }


    you can invoke this method while holding the lock as it follows:


    withLock(lock); {
      of(this).doSomething();
    }
    In this example it looks as if the lock is released before the block is executed, because it isn't passed to the method withLock.
  73. Re: free variable?[ Go to top ]

    Having defined the method withLock() as it follows:


    private void withLock(Lock lock) {
      Closure c = closure();
      try {
        lock.lock();
        c.apply();
      } finally {
        lock.unlock();
      }
    }


    if you have a doSomething() method:


    public void doSomething() {
      // do something here ...
    }


    you can invoke this method while holding the lock as it follows:


    withLock(lock); {
      of(this).doSomething();
    }


    In this example it looks as if the lock is released before the block is executed, because it isn't passed to the method withLock.
    Sorry, you are right, I made a stupid mistake. Actually in order to make my example work it has to be rewritten as it follows: private void withLock(Lock lock, Closure c) {   try {      lock.lock();     c.apply();   } finally {     lock.unlock();   } } public void doSomething() {   // do something here ... } Closure c = closure(); { of(this).doSomething(); } withLock(lock, c);
  74. Re: free variable?[ Go to top ]

    If I look at delegates in C# and then at the code below I would say that lambdaj is more of a Java delegate library. public int sum(int a, int b) { return a + b; } Closure2 adder = closure(Integer.class, Integer.class); { of(this).sum(var(Integer.class), var(Integer.class)); } One could post a little proposal for a Java delegate library on comp.lang.java or some other place or discuss things with some Java fellows. Then one might get some feedback indicating that something is missing or misunderstood which would be really useful to validate the approach. Just a suggestion ... Something like this might be considered useful: Method method = declaredMethod(this).sum(var(Integer.class), var(Integer.class)); method.invoke( ... );
  75. Re: free variable?[ Go to top ]

    If I look at delegates in C# and then at the code below I would say that lambdaj is more of a Java delegate library.
    I agree, probably the analogy with the C# delegates is closer to what lambdaj actually does. I believe I will rename "delegate" that feature in the next release in order to avoid any further misunderstandings. Anyway this is only one of the features of lambdaj. You can find the others features of the library here: http://code.google.com/p/lambdaj/wiki/LambdajFeatures
  76. Object iterable?[ Go to top ]

    Anyway this is only one of the features of lambdaj. You can find the others features of the library here:

    http://code.google.com/p/lambdaj/wiki/LambdajFeatures
    The API looks reasonably convenient. Could you explain the rationale for all the "Object iterable" (instead of "Iterable<!--? extends T--> iterable") in the method signatures of ch.lambdaj.Lambda? You have a comment in there referring to Lambda#forEach but I'm a bit slow on the uptake today.
  77. Re: Object iterable?[ Go to top ]

    The API looks reasonably convenient. Could you explain the rationale for all the "Object iterable" (instead of "Iterable iterable") in the method signatures of ch.lambdaj.Lambda? You have a comment in there referring to Lambda#forEach but I'm a bit slow on the uptake today.
    Even this choice could be questionable, but as I tried to explain the API of lambdaj are designed to be conveniently used in a single as readable as possible statement. Maybe a small example could be more explicative: supposing you have a list of persons, each person has a car and you want to find the fastest car you could write something like that: Car fastestCar = max(forEach(persons).getCar(), on(Car.class).getSpeed()); In this case, as you can imagine, the Car returned by the invocation: forEach(persons).getCar() is actually a proxy of that Car class that can be internally treated by lambdaj as an iterable of the cars of all the persons in the list. Let me know if now it makes sense.
  78. Re: Object iterable?[ Go to top ]

    Maybe a small example could be more explicative: supposing you have a list of persons, each person has a car and you want to find the fastest car you could write something like that:


    Car fastestCar = max(forEach(persons).getCar(), on(Car.class).getSpeed());


    In this case, as you can imagine, the Car returned by the invocation:


    forEach(persons).getCar()


    is actually a proxy of that Car class that can be internally treated by lambdaj as an iterable of the cars of all the persons in the list.

    Let me know if now it makes sense.
    Ah, yes I get it now. Thanks, Stefan
  79. Re: free variable?[ Go to top ]

    Sorry, you are right, I made a stupid mistake. Actually in order to make my example work it has to be rewritten as it follows:


    private void withLock(Lock lock, Closure c) {
      try { 
        lock.lock();
        c.apply();
      } finally {
        lock.unlock();
      }
    }

    public void doSomething() {
      // do something here ...
    }

    Closure c = closure(); { of(this).doSomething(); }
    withLock(lock, c);
    Given the structure of the lambdaj API, I would expect most of its users to make the same mistake. Repeatedly.
  80. Re: Let's go friends[ Go to top ]

    Besides, passing a block of code instead of a normal object around is very different from what java as a Object-Oriented language aims.
    Like an object in OO programming a closure contains code >andlove< it. In languages like Smalltalk loops, conditional expressions, and other things are all implemented using closures and are instances of a class Closure (in most Smalltalk systems called Context, HomeContext or Block). And an instance of a class by definition is an object.
  81. Re: Let's go friends[ Go to top ]

    Like an object in OO programming a closure contains code >and< state that is held in the closure's variables and free variables. Passing a closure around is therefore basically the same as passing an object around ...</blockquote> That's a good observation. In fact, it is possible to simulate the encapsulation (of methods and data) aspect of OO quite easily with nothing else but closures. You can also have several methods in your "objects" by having several closures that close over the same lexical scope. I'm not sure if there aren't some systems that implement their OO behavior in that way under the hood (OCaml perhaps?)
  82. Re: Let's go friends[ Go to top ]

    Like an object in OO programming a closure contains code >and< state that is held in the closure's variables and free variables. Passing a closure around is therefore basically the same as passing an object around ...</blockquote> There is no doubt that you can generalize the concept, but a class in java is much more cohesive and predictable. And a class *must* have a name.
  83. Re: Let's go friends[ Go to top ]

    There is no doubt that you can generalize the concept, but a class in java is much more cohesive and predictable.
    I once did the whole hierarchy ArrayList -> AbstractList -> AbstractCollection (entire API) in JavaScript using that approach (just to show myself it's possible, btw). It actually was very cohesive, easy-to-use and predictable from the call site (once you know the Java API). And I could implement private and protected visibility that way. I showed my code to a co-worker well-versed in JavaScript. He was scratching his head and didn't like it :)
    And a class *must* have a name.
    Yeah, and so what? Not all class-based OO languages use nominal typing, e.g. OCaml uses structural typing instead. Probably, you may have a very narrow view what OO can be? Kind regards, Stefan
  84. Structural typing[ Go to top ]

    Yeah, and so what? Not all class-based OO languages use nominal typing, e.g. OCaml uses structural typing instead. Probably, you may have a very narrow view what OO can be?
    To explain this a little further (in case you don't already know): In mainstream class-based OO languages we have nominal typing (i.e. typing based on the _name_ of the thing we extend or implement, hence "nominal"). In structural typing we have an "isAssignableFrom" relation between classes or interfaces based on the things a class can _do_, i.e. essentially the names and type signatures of its methods. This is like the "duck typing" thingy in runtime-tagged languages like Ruby, but it is enforced statically at compile-time. So, just a (warning: extreme!) example. Let's suppose we have two classes: "Camera" and "MachineGun". They don't have any kind of "is-a" relation, they don't extend each other, they don't implement a common interface. But both have a method "void shoot()". In OCaml one can write a function or class method whose only requirement would be that the Object passed in must have a method called "shoot" that doesn't take an argument and returns nothing and call the shoot() in that method (you can do the same thing in Scala, btw). The "O" in OCaml's type system is completely based on that notion of structural typing (as opposed to Scala, where it is a rather exceptional thing). I know, that sounds weird initially, but it gets less frightening (and may even appear logical) once you start studying it a little. I have no practical experience with OCaml, but I think it is self-consistent and definitely OO. So, yes, a class in OCaml has a name, but that fact doesn't buy you much ;) HTH, Stefan
  85. Re: Let's go friends[ Go to top ]

    Probably, you may have a very narrow view what OO can be?
    We are still talking about *java* here, right? Or at least should be.
  86. Re: Let's go friends[ Go to top ]

    Probably, you may have a very narrow view what OO can be?

    We are still talking about *java* here, right? Or at least should be.
    Oh, I assumed that it would be obvious to everyone that simulating a feature which Java already has (better and more efficient) through closures is utter nonsense. Also, Mr. Fusco mentioned Scala somwhere else. So, I thought we are talking about OO in general. But, never mind, of course we can restrict discussion to Java here.
  87. Re: Let's go friends[ Go to top ]

    Also, Mr. Fusco mentioned Scala somwhere else. So, I thought we are talking about OO in general. But, never mind, of course we can restrict discussion to Java here.
    Yes, I would like to talk about OO in general and I like Scala. But be aware that last time I tried to show some Java limitations and how Scala and other languages allow to overcome them, the biggest part of people in this forum were almost ready to kill me: http://www.theserverside.com/news/thread.tss?thread_id=55185
  88. Re: Let's go friends[ Go to top ]

    There is no doubt that you can generalize the concept, but a class in java is much more cohesive and predictable. And a class *must* have a name.
    Anyway, why wouldn't you create a class for calculating x + n ...
  89. This is exactly what I asked to mr. Gafter, since I cannot find it by myself: a practical example where an implementation of this traditional closure definition (and I doubt that BGGA completely adheres to it for other reasons) do something that the lambdaj implementation cannot do. Can you find it?
    I didn't understand that to be your question. For an answer, I suggest you see the video http://video.google.com/videoplay?docid=4051253555018153503 BGGA does indeed implement the traditional definition, though it has other features necessary to integrate it into the language.
  90. That binds to a constant, not a variable. The point is to use an identifier in the body of the lambda expression, and have that bound to a lexically enclosing variable. That is one of the defining features of closures, and the facility you describe lacks it.
    You weren't so hortodox when you defined the BGGA specification. Do the non-local return, break and continue remember you something? By the way I just realized somebody removed the presentation of Joshua Bloch about the BGGA controversy from its original position. Now the following URL just responds with a 404: http://www.javac.info/bloch-closures-controversy.ppt Do you know something about it, Neal? :)
  91. By the way I just realized somebody removed the presentation of Joshua Bloch about the BGGA controversy from its original position.
    It's still available here: http://www.parleys.com/display/PARLEYS/Home#title=The%20Closures%20Controversy;slide=1;talk=0
  92. Broken link[ Go to top ]

    Sorry, this is the link that works http://www.parleys.com/display/PARLEYS/The+Closures+Controversy
  93. You weren't so hortodox when you defined the BGGA specification. Do the non-local return, break and continue remember you something?
    Yes. For an explanation of how these fit into the "orthodox" definition of closures, see http://gafter.blogspot.com/2007/01/definition-of-closures.html
  94. I think what Neal's trying to say is, pseudo code below... var x = 10; var cl = { y => return x + y } print cl(10)
    20
    x = 20 print cl(10)
    30
    See how the variable that the closure enclosed has a runtime binding, though any changes to it at runtime is reflected in the closure. You can't do that in java period, due to the constraints on anonymous inner classes can only use final variables from outside of it's scope, though no matter what API you implement in java, it's not true closures. Ilya
  95. .....You can't do that in java period, due to the constraints on anonymous inner classes can only use final variables from outside of it's scope....
    final AtomicInteger x = new AtomicInteger(10); Closure cl = new Closure(){ public int invoke(int y){ return x.get() + y } } print cl(10)
    20
    x.set(20) print cl(10)
    30
    There you go,using anonymous inner classes, final fields, and allowing access to outside scope. Probably wouldn't use AtomicInteger but it's a standard class, to prove the point. Not super tidy but functional.Guess it depends on what you're trying to do. Cheers, Bert
  96. maven repo[ Go to top ]

    How do we include this in a maven project?
  97. Re: maven repo[ Go to top ]

    How do we include this in a maven project?
    At the moment you have to add the lambdaj repository to your pom file: http://lambdaj.googlecode.com/svn/repo/releases/ and then use respectively com.googlecode.lambdaj and lambdaj as groupId and arifactId. I asked to synchronize it with the maven central repository a few days ago and I am still waiting for an answer.
  98. I don't need Closures[ Go to top ]

    - I don't need Closures in Java. - I don't need obfuscated code like 'Closure println = closure(); { of(System.out).println(var(String.class)); }'. - I don't need snotty comments like 'If you still don't see how closures can be useful for you ...'. - I don't need contrieved samples like 'printFile(String fileName)'.
  99. Re: I don't need Closures[ Go to top ]

    Heh... I was using closures in Clipper in 1991. They were known as Code Blocks, and were handy as hell for implementing Command and Visitor patterns with such cross-cutting concerns such as security. Dave Rooney Mayford Technologies
  100. Re: I don't need Closures[ Go to top ]

    I totally agree, this is only unreadable and unmaintainable.
  101. Re: I don't need Closures[ Go to top ]

    I totally agree, this is only unreadable and unmaintainable.
    Are anonymous inner classes easier to read or coding by copy and paste easier to maintain?
  102. I don't know why but it looks like a huge marketing machine trying to sell closure to Java, so Java will be doomed for ever. I wonder and ask to these folks how the hell Java survived the last 14 years with out closure. If some one is dying to use closure, they have options of using Groovy, Scala, Clojure etc. They can always use these languages and many others to write lambada functions and make sure no body else can debug their programs, so their job will be safe for ever:-) Rashid.
  103. I don't know why but it looks like a huge marketing machine trying to sell closure to Java, so Java will be doomed for ever. I wonder and ask to these folks how the hell Java survived the last 14 years with out closure. If some one is dying to use closure, they have options of using Groovy, Scala, Clojure etc. They can always use these languages and many others to write lambada functions and make sure no body else can debug their programs, so their job will be safe for ever:-)
    Could you please rewrite the 3 public methods in the last example of this article in plain java without duplicating code and without using closures or anonymous inner classes? Thanks a lot Mario
  104. Could you please rewrite the 3 public methods in the last example of this article in plain java without duplicating code and without using closures or anonymous inner classes?
    but honestly is your closure syntax Closure1 lineReader = closure(String.class); { of(System.out).println(var(String.class)); } really better than the good old anonymous inner class Closure1 lineReader = new Closure1{ public void apply(String var) { System.out.println(var); } }; ? not by a lot I'd say.
  105. Inner class solution[ Go to top ]

    but honestly is your closure syntax

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

    really better than the good old anonymous inner class

    Closure1 lineReader = new Closure1{
    public void apply(String var)
    { System.out.println(var); } };
    not by a lot I'd say.
    If I'm getting it right (being very careful now ...) the point is that an inner class is allocated on the stack whereas a closure is allocated on the heap. If you wanted top pass the instance of the inner class you created on to some other object outside of the scope of the class that defines the inner class you would have to declare as final which removes the wanted flexibility as a final variable cannot be changed after it has been assigned. What is needed is a concise simple example where the problem with final when using inner classes is explained. Then all these "I don't need Closures in Java" would go away...
  106. Re: Inner class solution[ Go to top ]

    What is needed is a concise simple example where the problem with final when using inner classes is explained. Then all these "I don't need Closures in Java" would go away...
    See Advanced Topics In Programming Languages: Closures For Java.
  107. statically typed, interesting[ Go to top ]

    'closure' means different things to different people. I think your thing is better described as 'java method pointer' which unfortunately the language doesn't provide statically. This is the first time I know of an approach to reference a Java method in type-safe manner. very innovative. might be too smarty though.
  108. Hello Mr. Fusco, first of all, congratulations on the lambdaj 2.0 release! I've discovered the lambdaj project a few weeks ago, but was too busy to have a more detailed look so far. Keep on with the work - spreading FP concepts into the Java community certainly won't worsen future Java programs. Now some nitpicking: i) technically, what you're describing here are not closures as Neal Gafter has pointed out ii) "currying" refers to converting a function with n arguments to "a function with 1 argument that returns a function which takes 1 argument that returns a function which takes 1 argument ..." and so on (n times). What your "curry" is doing is more commonly known as "partial application". Though, you are in good company here, as (ironically) languages like Haskell which by definition don't have a need for currying often use the term "curry" when partial application is meant. Finally, I don't agree with your assessment of BGGA; quite on the contrary I think it is very well architected and every Java programmer interested in closures should look into it (and play with it http://www.javac.info/ ) *today*. Whatever will be coming in some Java 8, 9 or 3000, they'll be prepared. So, let's agree to differ here ;) Kind regards, Stefan
  109. API question[ Go to top ]

    The lamdaj library is designed with the goal to 'mimic' closures as close as possible. It enables you to write: Closure println = closure(); { of(System.out).println(var(String.class)); } That really puzzled me until I found the javadoc of Lambda.of(): static T of(T closed) Binds an object to the active closure that is the last one created in the current thread. So probably you are retaining the 'active closure' in a ThreadLocal. But what's wrong with the more obvious approach of saying Closure println = closure().of(System.out).println(var(String.class)); That's more concise and readable in a Java-context.
  110. Re: API question[ Go to top ]

    But what's wrong with the more obvious approach of saying

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

    That's more concise and readable in a Java-context.
    I'd like I could have implemented it in this way, but of course this is not feasible because the println() method of the PrintStream class returns void.
  111. Re: API question[ Go to top ]

    I'd like I could have implemented it in this way, but of course this is not feasible because the println() method of the PrintStream class returns void.
    So you would have Closure println = closure(); println.of(System.out).println(var(String.class)); Still more readable on the Java eye, IMHO. Did you consider using Double Brace Initialization idiom? E.g. like: Closure println = new Closure() {{ of(System.out).println(var(String.class)); }} Not everybody's cup of tea, but still less surprising than the ThreadLocal variable...
  112. 2 differents aspects[ Go to top ]

    There are actually 2 questions: 1. Are closures good for Java ? Hell yeah ! Closures are like babies: you think you know them but you don't until you're living with it (both are positive things, btw :) ) When you code a lot in JavaScript or ActionScript, and you come back to Java, you have to realize that you can't just pass some code as an argument ("just" means "without an anonymous inner class"). 2. Is it too late ? I don't think it is, but I'm not 200% sure. I'm just sure that it's a shame it hasn't been included before. It's one of the main regrets of James Gosling, who favors the BGGA proposal. What is even more hurtful is that we feel that they're not including it because of JavaFX...like they don't want Java and Swing to get too simple. Has Sun become the enemy of Java ? That I can't believe. Olivier Allouch
  113. Sorry, but IMHO this debate is a perfect illustration why closures and other many equally useless features were left out of the original Java design. If experts cannot agree on the semantics, what shall we mere mortals do:-) I don't think that closures can bring any significant improvement to the practice of Java SW development and the energy/time is probably better spent elsewhere. I usually spend much more time on design than on coding and ability to save a few lines of boilerplate is a consideration of a second order of magnitude, especially in view of the counter-intuitive syntax that hinders readability. Success of Java was brought about by simplicity of the language and comprehensiveness of the platform, attempts to bolt-on features with unclear practical utility are just a distraction.
  114. Success of Java was brought about by simplicity of the language and comprehensiveness of the platform, attempts to bolt-on features with unclear practical utility are just a distraction.
    +1
  115. Sorry, but IMHO this debate is a perfect illustration why closures and other many equally useless features were left out of the original Java design. If experts cannot agree on the semantics, what shall we mere mortals do:-)
    Who does decide what it is useless (in any possible case) and what it is not? I also have another question that I am wondering almost since I am interested in functional programming: why do people often feel the need to state they don't want or don't need it? I mean, for example, I don't like O/R mapping and I try to avoid to use Hibernate and similar tools when I can. But, in the same way, I don't go on forum that speaks about O/R mapping to say how useless it is or to confirm that I don't like it. So why do people do that when speaking about closure or functional programming in general?
  116. Market gets to decide, or in practical terms, popularity of the feature and level of use. I can only second your disapproval of O/R mapping technologies, and that is exactly the area where I would love to see some meaningful progress. But I fail to see how functional languages could bring that about. The reason I "invaded" is that IMO closures in Java will make the language less true to the original ideology of "everything is an object". And it might not be free - compromises on the ideological level tend to produce a stillborn.
  117. The reason I "invaded" is that IMO closures in Java will make the language less true to the original ideology of "everything is an object". And it might not be free - compromises on the ideological level tend to produce a stillborn.
    It isn't true that Java has been built on the original ideology that "everything is an object" and primitive types are there to prove it. Actually closures could only bring that sentence closer to the truth since by having them even functions could become objects.
  118. Sorry, but IMHO this debate is a perfect illustration why closures and other many equally useless features were left out of the original Java design. If experts cannot agree on the semantics, what shall we mere mortals do:-)
    "When a function refers to a variable defined outside it, it's called a free variable. A function that refers to a free lexical variable is called a closure. (...) The name "closure" is a left over from earlier Lisp dialects. It derives from the way closures have to to be implemented under dynamic scope." Paul Graham, ANSI Common Lisp, Prentice Hall, 1996, p.107. Nevertheless, this thing about free variables "is only a trivial detail", right? These constructs in lambdaj are not closures. They might be useful for many things if not considered obfuscated code, but they should not be called closures. Mr.Gafter only tried to point out what Mr.Graham has said long time ago. In Smalltalk-80 you can do the same thing as in Common Lisp and Smalltalk-80 was published in 1980, hence the name. So experts agree at least for almost 30 years and there is no disagreement between experts here at all. There is only a problem with some people that only want to learn things that are new and believe something is pointless only because it was invented long time ago. The C# team just added closures and delegates to the language and didn't care whether any former Visual Basic developers that now develop in C# would see that kind of things for the first time. I think Sun/Oracle should just do the same thing and please add mixins as well.
  119. Just found this one: http://blogs.sun.com/darcy/entry/project_coin_final_five