I seem to be detecting a pattern in the contributions to the debate on closures. And its based on the prior programming language experience of the contributor. Which kind of person are you?
- Functional - Like Haskell. See closures as functions, and a way to do lots of clever FP black magic. Typically also argue for currying and tail-order recursion. Unwilling to accept that Java isn't and never will be a functional language.
- Dynamic - Like Ruby, Groovy or Smalltalk. See closures as methods on objects, which are the primary means to loop, read files, etc. Initially like the idea of closures in Java but see the implementation as too verbose. Typically also argue for extra methods on the Java Collection or List interface, and type inference. Find it very difficult to move back from the dynamic-typed language to the static-typed Java where a lot more keypresses are required.
- Java-lover - Like Java and may well not have seen much else. See closures as an alternative to inner classes with strange, different rules. Typically argue for simpler syntax for inner classes instead of closures. Unwilling to look beyond Java - if it ain't broke, don't fix it.
I hope I'm not be too cruel by categorizing this - please don't hold it against me!!! There are of course many people who don't fit this model, but its a basis to start from. And remember, its framed in terms of responses to the idea of closures in Java.
And me? Well I was in the last camp - the Java-lover. But I've now explored just enough of the dynamic world to see how closures work there. And I can now understand the desire for the dynamic crowd to have closures as regular methods - list.each() for example. However, I'm far from convinced that the method-style invocation of a closure fits the Java-style or mentality.
And that's the point of this blog post. If closures are added to Java, then the syntax must feel right and understandable to the third group above - Java-lovers. And it seems to me that the keyword-style invocation is much more palatable to that group. Of course, as such, the proposal feels wrong to most in the functional and dynamic groups.
BTW. That's why I use the keyword style syntax for all my examples of closures. Because in the end, I believe that style is what will be most understood by Java developers. And probably most hated by the dynamic and functional groups!
I am a mixture between the functional and the Java-lover.
ReplyDeleteI like both forms, but I think I need to see some use cases in the expression form - I'm not sure whether that form should allow multiple statements yet; or if it should, whether a multiple-statement expression-form closure should be able to return anything.
Note that not all statically typed systems are verbose - Haskell compares well to Ruby et al in brevity. In fact, an advanced Haskell user can probably reduce your entire 20k loc project to 2 lines of trivial Haskell. ;)
I learnt Miranda at Uni, which is very similar to Haskell. At the time, I appreciated it's incredible power, but I did have some problems employing it. It could however be that I wasn't applying myself to it as I would do now. ;)
ReplyDeleteSo, I'd love to access that kind of power in my favouite language of Java. I think it is good to have the syntax more Java-like, because it's Java after all! I'm glad this wasn't added earlier though. Now that Java development is much more community focused, this feature much more likely to get the attention it deserves, and hopefully all the details are ironed out, and we get the best implementation possible.
So, I guess I am the Java lover with enough functional background to know that this could really revolutionise our code (and hopefully Java itself).
BTW, I enjoyed your talk on JodaTime at Javapolis! I added the deprecation of Date,Calendar,TimeZone suggestion to the whitebords - we have just had *so* many problems, bugs, and nightmare implementations (particularly with daylight savings problems in Date) dealing with dates. I'm trying to advocate it's use within my company. I'm for a JSR! About one of your previous posts: I think you *need* to be a Sun person to lead a JSR don't you? I think that is something Neal Gafter metioned in his closures talk...
I'm sitting between dynamic camp and the Java camp as well. A nice syntax? Well I still argue that something akin to what you see in current implementations is very readable. It opens with the curly brace, places the passed in variable declarations within a pair of pipes, and can have multiple statements. A Ruby example:
ReplyDeletemylist.each {|item|
puts "{#item} = {#item.size}\n"
}
In Java it would look something like this (using the form of closure method that I don't fully agree with):
each( mylist, {|String item|
System.out.print( item );
System.out.print( " = " );
System.out.println( item.length() );
});
I personally think the syntax works, even for a Java guy. Why re-invent a common syntax? It does make Java a bit more accessible to a wider crew. And yes I agree that forcing Java (or Ruby for that matter) into a functional mold is wrong. It's Object Oriented.
Java's object orientated where it chooses to be; primitives are not objects, code blocks are not objects. The BGGA proposal actually lets code blocks be objects.
ReplyDeleteJava is already a multi-paradigm language - people are writing in a functional way, some in a procedural way, and many variations of what people call OO.
Objects themselves are insufficient to control an entire program, that's why we need a procedural layer (such as public static void main, and static methods in general). If I'm wrong, the contradiction will probably come from Smalltalk, a language I don't know.
The best Java interfaces are those that are the most trivial (consider ActionListener as opposed to ResultSet). One-method interfaces are the ultimate, so trivial that they really are functions (or procedures).
Scala's mixin ability looks interesting; you can have an object with one method, then make a view that makes the same object look like it's got lots of other methods. This keeps the object simple (in BGGA terms the object code be a closure), but lets you conveniently use other methods, i.e., thing.operateOn(), rather than ThingUtility.operateOn(thing). Yes, I know about static imports. The view in Scala is localised, two parts of your app can view the same object in two different ways.
In short, functional programming is the logical conclusion of object orientated programming - objects are a nice way of looking at functions.
I'd say I'm functional, except that I agree that Java isn't and never will be a functional language.
ReplyDeleteStill, if Java is to have closures, they should work at least as well as they do in Groovy. Your point about updating lists instead of returning copies on the last post doesn't stand. If traversing a List to get their names, you will need a List as a result.
Currying and tail recursion exist for a reason, and since we're adding something completely new to the language, Java closures should benefit from all the experience and knowledge acquired in other languages.
Please catch the NotInventedHereException.