-
lambdaj 2.0 brings (almost) real closures to Java (118 messages)
- Posted by: Mario Fusco
- Posted on: August 24 2009 08:00 EDT
[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)
- AS good as you can mimic closures by Olli Plough on August 24 2009 09:59 EDT
- Re: AS good as you can mimic closures by Mario Fusco on August 24 2009 10:14 EDT
-
Re: Re: As good as you can mimic closures by Olli Plough on August 24 2009 10:36 EDT
- Re: Re: As good as you can mimic closures by Mario Fusco on August 24 2009 10:46 EDT
-
Re: Re: As good as you can mimic closures by Olli Plough on August 24 2009 10:36 EDT
- Re: AS good as you can mimic closures by Ashwin Jayaprakash on August 24 2009 13:17 EDT
- Re: AS good as you can mimic closures by Mario Fusco on August 24 2009 10:14 EDT
- Why Closure.apply() returns Object? by Leandro Aparecido on August 24 2009 11:47 EDT
- Re: Why Closure.apply() returns Object? by Mario Fusco on August 24 2009 12:37 EDT
- You don't know what a free variable is, do you? by Neal Gafter on August 24 2009 11:58 EDT
- Re: You don't know what a free variable is, do you? by Mario Fusco on August 24 2009 12:22 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 24 2009 02:08 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 24 2009 02:17 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 01:49 EDT
-
Re: You don't know what a free variable is, do you? by Jose Maria Arranz on August 25 2009 02:52 EDT
- Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 03:39 EDT
- Re: You don't know what a free variable is, do you? by Jose Maria Arranz on August 25 2009 03:48 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 03:01 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 06:56 EDT
- Binding a free variable by Stefan Zobel on August 25 2009 07:09 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 07:45 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 08:18 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 08:30 EDT
- Scope by Stefan Zobel on August 25 2009 09:31 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 08:30 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 08:18 EDT
- params being declared final by Olli Plough on August 25 2009 08:22 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 11:02 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 11:11 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 11:19 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 11:33 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 02:14 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 02:31 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 04:34 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 04:54 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 05:48 EDT
-
Let's go friends by Olli Plough on August 25 2009 06:06 EDT
- Re: Let's go friends by Mario Fusco on August 25 2009 06:29 EDT
-
Re: Let's go friends by Stefan Zobel on August 25 2009 08:15 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 09:24 EDT
-
Re: Let's go friends by Olli Plough on August 26 2009 10:44 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 11:44 EDT
-
Re: Let's go friends by Mario Fusco on August 26 2009 11:56 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 12:17 EDT
-
Re: Let's go friends by Mario Fusco on August 26 2009 12:29 EDT
- Re: Let's go friends by Leandro Aparecido on August 26 2009 12:55 EDT
-
Re: Let's go friends by Stefan Zobel on August 26 2009 03:13 EDT
-
free variable? by tasos zervos on August 27 2009 05:51 EDT
-
Re: free variable? by tasos zervos on August 27 2009 06:25 EDT
-
Re: free variable? by Olli Plough on August 27 2009 08:03 EDT
-
Re: free variable? by Mario Fusco on August 27 2009 08:48 EDT
-
Re: free variable? by Neal Gafter on August 27 2009 11:02 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 11:52 EDT
-
Re: free variable? by Mario Fusco on August 27 2009 01:20 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 02:28 EDT
-
Re: free variable? by Olli Plough on August 27 2009 05:38 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 05:51 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 06:03 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 05:51 EDT
-
Re: free variable? by Olli Plough on August 27 2009 05:38 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 02:34 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 02:57 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 03:03 EDT
-
Re: free variable? by Neal Gafter on August 27 2009 03:21 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 03:32 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 03:14 EDT
-
Readability by Stefan Zobel on August 28 2009 08:31 EDT
-
Re: Readability by Mario Fusco on August 29 2009 05:17 EDT
-
Re: Readability by Stefan Zobel on August 29 2009 02:10 EDT
-
Re: Readability by Mario Fusco on August 30 2009 07:49 EDT
-
Re: Readability by Neal Gafter on August 31 2009 11:56 EDT
-
Re: Readability by Stefan Zobel on August 31 2009 01:36 EDT
-
Re: Readability by Neal Gafter on August 31 2009 02:15 EDT
- Re: Readability by Stefan Zobel on August 31 2009 02:50 EDT
-
Re: Readability by Neal Gafter on August 31 2009 02:15 EDT
-
Re: Readability by Stefan Zobel on August 31 2009 01:36 EDT
-
Re: Readability by Neal Gafter on August 31 2009 11:56 EDT
-
Re: Readability by Mario Fusco on August 30 2009 07:49 EDT
-
Re: Readability by Stefan Zobel on August 29 2009 02:10 EDT
-
Re: Readability by Mario Fusco on August 29 2009 05:17 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 02:28 EDT
-
Re: free variable? by Mario Fusco on August 27 2009 01:20 EDT
- Re: free variable? by Stefan Zobel on August 27 2009 12:09 EDT
-
Re: free variable? by Mario Fusco on August 27 2009 05:23 EDT
-
Re: free variable? by Neal Gafter on August 27 2009 06:35 EDT
-
Re: free variable? by Mario Fusco on August 28 2009 03:11 EDT
-
Re: free variable? by Olli Plough on August 28 2009 05:37 EDT
-
Re: free variable? by Mario Fusco on August 28 2009 06:05 EDT
-
Object iterable? by Stefan Zobel on August 28 2009 11:43 EDT
-
Re: Object iterable? by Mario Fusco on August 28 2009 12:35 EDT
- Re: Object iterable? by Stefan Zobel on August 28 2009 01:11 EDT
-
Re: Object iterable? by Mario Fusco on August 28 2009 12:35 EDT
-
Object iterable? by Stefan Zobel on August 28 2009 11:43 EDT
-
Re: free variable? by Mario Fusco on August 28 2009 06:05 EDT
- Re: free variable? by Neal Gafter on August 28 2009 06:02 EDT
-
Re: free variable? by Olli Plough on August 28 2009 05:37 EDT
-
Re: free variable? by Mario Fusco on August 28 2009 03:11 EDT
-
Re: free variable? by Neal Gafter on August 27 2009 06:35 EDT
-
Re: free variable? by Stefan Zobel on August 27 2009 11:52 EDT
-
Re: free variable? by Neal Gafter on August 27 2009 11:02 EDT
-
Re: free variable? by Mario Fusco on August 27 2009 08:48 EDT
-
Re: free variable? by Olli Plough on August 27 2009 08:03 EDT
-
Re: free variable? by tasos zervos on August 27 2009 06:25 EDT
-
free variable? by tasos zervos on August 27 2009 05:51 EDT
-
Re: Let's go friends by Mario Fusco on August 26 2009 12:29 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 12:17 EDT
-
Re: Let's go friends by Olli Plough on August 26 2009 04:23 EDT
-
Re: Let's go friends by Stefan Zobel on August 26 2009 04:43 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 05:07 EDT
-
Re: Let's go friends by Stefan Zobel on August 26 2009 05:32 EDT
- Structural typing by Stefan Zobel on August 26 2009 06:18 EDT
-
Re: Let's go friends by Leandro Aparecido on August 27 2009 09:57 EDT
-
Re: Let's go friends by Stefan Zobel on August 27 2009 10:35 EDT
- Re: Let's go friends by Mario Fusco on August 27 2009 10:56 EDT
-
Re: Let's go friends by Stefan Zobel on August 27 2009 10:35 EDT
- Re: Let's go friends by Olli Plough on August 27 2009 03:51 EDT
-
Re: Let's go friends by Stefan Zobel on August 26 2009 05:32 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 05:07 EDT
-
Re: Let's go friends by Stefan Zobel on August 26 2009 04:43 EDT
-
Re: Let's go friends by Mario Fusco on August 26 2009 11:56 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 11:44 EDT
-
Re: Let's go friends by Olli Plough on August 26 2009 10:44 EDT
-
Re: Let's go friends by Leandro Aparecido on August 26 2009 09:24 EDT
-
Let's go friends by Olli Plough on August 25 2009 06:06 EDT
- Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 09:48 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 05:48 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 04:54 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 04:34 EDT
-
Re: You don't know what a free variable is, do you? by Tommaso Aniello on August 25 2009 03:23 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 03:37 EDT
- Broken link by Stefan Zobel on August 25 2009 03:42 EDT
- Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 08:15 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 03:37 EDT
-
Re: You don't know what a free variable is, do you? by Ilya Sterin on August 26 2009 12:27 EDT
- Re: You don't know what a free variable is, do you? by Bert van Brakel on November 17 2009 06:38 EST
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 02:31 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 02:14 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 11:33 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 11:19 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 25 2009 11:11 EDT
-
Re: You don't know what a free variable is, do you? by Stefan Zobel on August 25 2009 06:56 EDT
-
Re: You don't know what a free variable is, do you? by Jose Maria Arranz on August 25 2009 02:52 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 25 2009 01:49 EDT
-
Re: You don't know what a free variable is, do you? by Mario Fusco on August 24 2009 02:17 EDT
-
Re: You don't know what a free variable is, do you? by Neal Gafter on August 24 2009 02:08 EDT
- Re: You don't know what a free variable is, do you? by Mario Fusco on August 24 2009 12:22 EDT
- maven repo by Praveen Govindan on August 24 2009 13:00 EDT
- Re: maven repo by Mario Fusco on August 24 2009 13:07 EDT
- I don't need Closures by Casual Visitor on August 24 2009 15:43 EDT
- Re: I don't need Closures by Dave Rooney on August 24 2009 16:23 EDT
- Re: I don't need Closures by Arne Nilsson on August 25 2009 04:35 EDT
- Re: I don't need Closures by Mario Fusco on August 25 2009 04:41 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Rashid Jilani on August 24 2009 17:58 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Mario Fusco on August 24 2009 18:21 EDT
-
Re: lambdaj 2.0 brings (almost) real closures to Java by J Yu on August 24 2009 07:13 EDT
-
Inner class solution by Olli Plough on August 25 2009 03:32 EDT
- Re: Inner class solution by Neal Gafter on August 25 2009 11:10 EDT
-
Inner class solution by Olli Plough on August 25 2009 03:32 EDT
-
Re: lambdaj 2.0 brings (almost) real closures to Java by J Yu on August 24 2009 07:13 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Mario Fusco on August 24 2009 18:21 EDT
- statically typed, interesting by J Yu on August 24 2009 19:00 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Stefan Zobel on August 24 2009 19:46 EDT
- API question by Hes Siemelink on August 25 2009 05:49 EDT
- Re: API question by Mario Fusco on August 25 2009 05:58 EDT
- Re: API question by Hes Siemelink on August 25 2009 07:29 EDT
- Re: API question by Mario Fusco on August 25 2009 05:58 EDT
- 2 differents aspects by Olivier Allouch on August 25 2009 10:08 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Azary Smotrich on August 25 2009 16:48 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Ethan Allen on August 25 2009 16:57 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Mario Fusco on August 25 2009 17:16 EDT
-
Re: lambdaj 2.0 brings (almost) real closures to Java by Azary Smotrich on August 25 2009 06:07 EDT
- Re: lambdaj 2.0 brings (almost) real closures to Java by Mario Fusco on August 25 2009 06:16 EDT
-
Re: lambdaj 2.0 brings (almost) real closures to Java by Azary Smotrich on August 25 2009 06:07 EDT
- What does mit Paul Graham say to this? by Olli Plough on August 25 2009 17:37 EDT
- What to expect from JDK 7 seems to be finally settled by Stefan Zobel on August 29 2009 20:37 EDT
-
AS good as you can mimic closures[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 24 2009 09:59 EDT
- in response to Mario Fusco
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. -
Re: AS good as you can mimic closures[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 10:14 EDT
- in response to Olli Plough
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:
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.
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.
I'm afraid you will wait for long long time then. -
Re: Re: As good as you can mimic closures[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 24 2009 10:36 EDT
- in response to Mario Fusco
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. -
Re: Re: As good as you can mimic closures[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 10:46 EDT
- in response to Olli Plough
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 -
Re: AS good as you can mimic closures[ Go to top ]
- Posted by: Ashwin Jayaprakash
- Posted on: August 24 2009 13:17 EDT
- in response to Olli Plough
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). -
Why Closure.apply() returns Object?[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 24 2009 11:47 EDT
- in response to Mario Fusco
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? -
Re: Why Closure.apply() returns Object?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 12:37 EDT
- in response to Leandro Aparecido
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: https://www.theserverside.com/news/thread.tss?thread_id=55185 -
You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 24 2009 11:58 EDT
- in response to Mario Fusco
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 12:22 EDT
- in response to Neal Gafter
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."
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
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 24 2009 14:08 EDT
- in response to Mario Fusco
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 14:17 EDT
- in response to Neal Gafter
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? -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 01:49 EDT
- in response to Mario Fusco
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Jose Maria Arranz
- Posted on: August 25 2009 02:52 EDT
- in response to Neal Gafter
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 :) -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 03:39 EDT
- in response to Jose Maria Arranz
I can't understand the obsession behind phrases like "Java is going to die because closures are missing".
Probably that's why lots of people refer to anonymous inner classes as the poor man's closure :)
A sort of closures is already in Java since v1.1, by the way thanks to Neal Gafter and others (am I wrong Neal?).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.
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.
I will welcome more compact closures in Java like BGGA proposalbut 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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Jose Maria Arranz
- Posted on: August 25 2009 03:48 EDT
- in response to Jose Maria Arranz
A "return" is missing: Closure plus(int n) { return int(x){return x+n}; } Anyway lambdaj is a interesting try. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 03:01 EDT
- in response to Neal Gafter
Using BGGA syntax (and assuming an interface "Closure" is defined in scope):
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
/** 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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 06:56 EDT
- in response to Mario Fusco
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, StefanUsing 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 -
Binding a free variable[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 07:09 EDT
- in response to Stefan Zobel
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 } -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 07:45 EDT
- in response to Stefan Zobel
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 }
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 -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 08:18 EDT
- in response to Mario Fusco
I could rewrite my example accordingly to your modifications and still not seeing any difference:
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.
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
}The free variables of a closure are, by definition, bound when the closure is created (not when invoked).
-
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 08:30 EDT
- in response to Stefan Zobel
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.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). -
Scope[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 09:31 EDT
- in response to Mario Fusco
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 -
params being declared final[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 25 2009 08:22 EDT
- in response to Stefan Zobel
Now, do you see the difference?
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.
Kind regards,
Stefan -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 11:02 EDT
- in response to Mario Fusco
In which part your example differs from the following?
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.
Closure1 plus10 = closure(Integer.class, Integer.class); { of(this).plus(var(Integer.class), 10); }
System.out.println(plus10.apply(2)); // prints 12 -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 11:11 EDT
- in response to Neal Gafter
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.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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 11:19 EDT
- in response to Mario Fusco
In the same way you write:
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.
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 11:33 EDT
- in response to Neal Gafter
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?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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 14:14 EDT
- in response to Mario Fusco
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
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.
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? -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 14:31 EDT
- in response to Neal Gafter
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 16:34 EDT
- in response to Mario Fusco
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:
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
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 16:54 EDT
- in response to Stefan Zobel
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 -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 17:48 EDT
- in response to Mario Fusco
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?
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
Thank you
Mario -
Let's go friends[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 25 2009 18:06 EDT
- in response to Stefan Zobel
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 ... -
Re: Let's go friends[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 18:29 EDT
- in response to Olli Plough
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.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.
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.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 ... -
Re: Let's go friends[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 20:15 EDT
- in response to Olli Plough
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". -
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 26 2009 09:24 EDT
- in response to Stefan Zobel
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. -
Re: Let's go friends[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 26 2009 10:44 EDT
- in response to Leandro Aparecido
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 ... -
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 26 2009 11:44 EDT
- in response to Olli Plough
"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.
-
Re: Let's go friends[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 26 2009 11:56 EDT
- in response to Leandro Aparecido
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. -
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 26 2009 12:17 EDT
- in response to Mario Fusco
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. -
Re: Let's go friends[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 26 2009 12:29 EDT
- in response to Leandro Aparecido
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 :) -
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 26 2009 12:55 EDT
- in response to Mario Fusco
And do you believe to know what is more useful for the majority of users?
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.
I feel happy when I discover what is more useful for me and my team :) -
Re: Let's go friends[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 26 2009 15:13 EDT
- in response to Leandro Aparecido
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.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. -
free variable?[ Go to top ]
- Posted by: tasos zervos
- Posted on: August 27 2009 05:51 EDT
- in response to Stefan Zobel
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? -
Re: free variable?[ Go to top ]
- Posted by: tasos zervos
- Posted on: August 27 2009 06:25 EDT
- in response to tasos zervos
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? -
Re: free variable?[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 27 2009 08:03 EDT
- in response to tasos zervos
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.htmlIf 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". -
Re: free variable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 27 2009 08:48 EDT
- in response to Olli Plough
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. -
Re: free variable?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 27 2009 11:02 EDT
- in response to Mario Fusco
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 -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 11:52 EDT
- in response to Neal Gafter
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! -
Re: free variable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 27 2009 13:20 EDT
- in response to Stefan Zobel
>Exactly.
That's why I started writing lambdaj. I am sure you cannot find anything similar in it.
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!
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. -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 14:28 EDT
- in response to Mario Fusco
I suppose you mean something easy to be managed like that:
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.
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. -
Re: free variable?[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 27 2009 17:38 EDT
- in response to Stefan Zobel
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. -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 17:51 EDT
- in response to Olli Plough
The type of the return value?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. -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 18:03 EDT
- in response to Stefan Zobel
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. -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 14:34 EDT
- in response to Mario Fusco
You (or Joshua Bloch) seems to have the type parameter wrong, btw. I think it should be <{ => int },{ => int}> not <{ => int },{ int => }>
static Pair<{ => int },{ int => }> joinedCounters(int initial) {
  return Pair.<{ => int },{ int => }>of(
    { => intial++ }, { => intial++ });
} -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 14:57 EDT
- in response to Mario Fusco
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). -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 15:03 EDT
- in response to Stefan Zobel
This site somehow likes to balance the angle brackets, so it inserts a wrong closing angle after the Pair<Func </code> -
Re: free variable?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 27 2009 15:21 EDT
- in response to Stefan Zobel
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()); } } -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 15:32 EDT
- in response to Neal Gafter
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.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());
}
} -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 15:14 EDT
- in response to Mario Fusco
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 -
Readability[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 28 2009 20:31 EDT
- in response to Mario Fusco
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. -
Re: Readability[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 29 2009 05:17 EDT
- in response to Stefan Zobel
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? -
Re: Readability[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 29 2009 14:10 EDT
- in response to Mario Fusco
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 comIt'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?
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 -
Re: Readability[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 30 2009 07:49 EDT
- in response to Stefan Zobel
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.
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.
BGGA was the most "visible" of these, so it received the most attention.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 ( https://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.
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
Cheers,
Stefan -
Re: Readability[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 31 2009 11:56 EDT
- in response to Mario Fusco
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. -
Re: Readability[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 31 2009 13:36 EDT
- in response to Neal Gafter
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 -
Re: Readability[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 31 2009 14:15 EDT
- in response to Stefan Zobel
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 -
Re: Readability[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 31 2009 14:50 EDT
- in response to Neal Gafter
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. -
Re: free variable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 12:09 EDT
- in response to Neal Gafter
Have you seen the video?: http://video.google.com/videoplay?docid=4051253555018153503
It very, very good. Highly recommended. -
Re: free variable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 27 2009 17:23 EDT
- in response to Neal Gafter
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(); } -
Re: free variable?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 27 2009 18:35 EDT
- in response to Mario Fusco
Having defined the method withLock() as it follows:
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.
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();
} -
Re: free variable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 28 2009 03:11 EDT
- in response to Neal Gafter
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);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. -
Re: free variable?[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 28 2009 05:37 EDT
- in response to Mario Fusco
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( ... ); -
Re: free variable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 28 2009 06:05 EDT
- in response to Olli Plough
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 -
Object iterable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 28 2009 11:43 EDT
- in response to Mario Fusco
Anyway this is only one of the features of lambdaj. You can find the others features of the library here:
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.
http://code.google.com/p/lambdaj/wiki/LambdajFeatures -
Re: Object iterable?[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 28 2009 12:35 EDT
- in response to Stefan Zobel
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. -
Re: Object iterable?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 28 2009 13:11 EDT
- in response to Mario Fusco
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:
Ah, yes I get it now. Thanks, Stefan
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. -
Re: free variable?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 28 2009 18:02 EDT
- in response to Mario Fusco
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:
Given the structure of the lambdaj API, I would expect most of its users to make the same mistake. Repeatedly.
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); -
Re: Let's go friends[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 26 2009 16:23 EDT
- in response to Leandro Aparecido
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. -
Re: Let's go friends[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 26 2009 16:43 EDT
- in response to Olli Plough
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?)
-
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 26 2009 17:07 EDT
- in response to Stefan Zobel
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.
-
Re: Let's go friends[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 26 2009 17:32 EDT
- in response to Leandro Aparecido
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 -
Structural typing[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 26 2009 18:18 EDT
- in response to Stefan Zobel
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 -
Re: Let's go friends[ Go to top ]
- Posted by: Leandro Aparecido
- Posted on: August 27 2009 09:57 EDT
- in response to Stefan Zobel
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. -
Re: Let's go friends[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 27 2009 10:35 EDT
- in response to Leandro Aparecido
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.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. -
Re: Let's go friends[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 27 2009 10:56 EDT
- in response to Stefan Zobel
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: https://www.theserverside.com/news/thread.tss?thread_id=55185 -
Re: Let's go friends[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 27 2009 03:51 EDT
- in response to Leandro Aparecido
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 ... -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 21:48 EDT
- in response to Mario Fusco
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. -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Tommaso Aniello
- Posted on: August 25 2009 15:23 EDT
- in response to Neal Gafter
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? :) -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 15:37 EDT
- in response to Tommaso Aniello
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 -
Broken link[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 25 2009 15:42 EDT
- in response to Stefan Zobel
Sorry, this is the link that works http://www.parleys.com/display/PARLEYS/The+Closures+Controversy -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 20:15 EDT
- in response to Tommaso Aniello
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 -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Ilya Sterin
- Posted on: August 26 2009 00:27 EDT
- in response to Neal Gafter
I think what Neal's trying to say is, pseudo code below... var x = 10; var cl = { y => return x + y } print cl(10)x = 20 print cl(10)20See 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. Ilya30 -
Re: You don't know what a free variable is, do you?[ Go to top ]
- Posted by: Bert van Brakel
- Posted on: November 17 2009 18:38 EST
- in response to Ilya Sterin
.....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)x.set(20) print cl(10)20There 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, Bert30 -
maven repo[ Go to top ]
- Posted by: Praveen Govindan
- Posted on: August 24 2009 13:00 EDT
- in response to Mario Fusco
How do we include this in a maven project? -
Re: maven repo[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 13:07 EDT
- in response to Praveen Govindan
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. -
I don't need Closures[ Go to top ]
- Posted by: Casual Visitor
- Posted on: August 24 2009 15:43 EDT
- in response to Mario Fusco
- 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)'. -
Re: I don't need Closures[ Go to top ]
- Posted by: Dave Rooney
- Posted on: August 24 2009 16:23 EDT
- in response to Casual Visitor
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 -
Re: I don't need Closures[ Go to top ]
- Posted by: Arne Nilsson
- Posted on: August 25 2009 04:35 EDT
- in response to Casual Visitor
I totally agree, this is only unreadable and unmaintainable. -
Re: I don't need Closures[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 04:41 EDT
- in response to Arne Nilsson
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? -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Rashid Jilani
- Posted on: August 24 2009 17:58 EDT
- in response to Mario Fusco
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. -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 24 2009 18:21 EDT
- in response to Rashid Jilani
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 -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: J Yu
- Posted on: August 24 2009 19:13 EDT
- in response to Mario Fusco
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. -
Inner class solution[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 25 2009 03:32 EDT
- in response to J Yu
but honestly is your closure syntax
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...
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. -
Re: Inner class solution[ Go to top ]
- Posted by: Neal Gafter
- Posted on: August 25 2009 11:10 EDT
- in response to Olli Plough
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. -
statically typed, interesting[ Go to top ]
- Posted by: J Yu
- Posted on: August 24 2009 19:00 EDT
- in response to Mario Fusco
'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. -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 24 2009 19:46 EDT
- in response to Mario Fusco
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 -
API question[ Go to top ]
- Posted by: Hes Siemelink
- Posted on: August 25 2009 05:49 EDT
- in response to Mario Fusco
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. -
Re: API question[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 05:58 EDT
- in response to Hes Siemelink
But what's wrong with the more obvious approach of saying
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.
Closure println = closure().of(System.out).println(var(String.class));
That's more concise and readable in a Java-context. -
Re: API question[ Go to top ]
- Posted by: Hes Siemelink
- Posted on: August 25 2009 07:29 EDT
- in response to Mario Fusco
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... -
2 differents aspects[ Go to top ]
- Posted by: Olivier Allouch
- Posted on: August 25 2009 10:08 EDT
- in response to Mario Fusco
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 -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Azary Smotrich
- Posted on: August 25 2009 16:48 EDT
- in response to Mario Fusco
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. -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Ethan Allen
- Posted on: August 25 2009 16:57 EDT
- in response to Azary Smotrich
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 -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 17:16 EDT
- in response to Azary Smotrich
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? -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Azary Smotrich
- Posted on: August 25 2009 18:07 EDT
- in response to Mario Fusco
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. -
Re: lambdaj 2.0 brings (almost) real closures to Java[ Go to top ]
- Posted by: Mario Fusco
- Posted on: August 25 2009 18:16 EDT
- in response to Azary Smotrich
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. -
What does mit Paul Graham say to this?[ Go to top ]
- Posted by: Olli Plough
- Posted on: August 25 2009 17:37 EDT
- in response to Azary Smotrich
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. -
What to expect from JDK 7 seems to be finally settled[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: August 29 2009 20:37 EDT
- in response to Mario Fusco
Just found this one: http://blogs.sun.com/darcy/entry/project_coin_final_five