Java 7: Oracle pushes a first version of closures
baptiste-wicht.com
baptiste-wicht.com
Collections.sort(list, (Comparator) #(String a, String b) {
return a.compareToIgnoreCase(b);
}); Comparator string_lessp = (Comparator) #(String a, String b) {
return a.compareToIgnoreCase(b);
}
sort(list, string_lessp);Anyway, the point was only that "(sort list #'string-lessp)" is nothing special.
I am fully onboard with closures as semantically equivalent to an anonymous class with a single method. The current syntax for creating them, though, is ridiculous.
I don't think the current syntax for anonymous classes is 'ridiculous', it's just inconveniently verbose when you only want a single method. If you're implementing a more complex interface, the current method is actually pretty good.
Java often completely ignores the design guideline of making the easy things easy and the hard things possible, preferring just to make the hard things possible. Anonymous inner classes with many methods are far less commonly needed than anonymous functions, and it's rare that the program is better served having them inline rather than defined elsewhere anyways.
Five lines and dozens of characters of boilerplate for every anonymous function does come at a cost and is ridiculous.
That's it exactly. My "favorite" example is file I/O. Yes, it's great that I can chain a bunch of InputStream instances together to read encrypted gzipped serialized objects over the network, but it shouldn't be more than one line for the far more common case of reading a file's contents into a string or a byte array.
Just to play devil's advocate, what is unusable about the syntax for anonymous classes in Java? An example close to bnoordhuis's post below, in today's syntax:
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer i1, Integer i2) {
return i1.compareTo(i2);
}
});
How are closures going to help?Everyone looking for these kind of features should probably just be using Scala...
1) For now, I still have a job as a Java programmer. Closures in Java will save me some lines of code until I can fix that.
2) Currently each JVM language has its own incompatible reinvention of closures. I think that closures in Java are a step towards better interoperability between JVM languages.
3) A lot of programmers will be introduced to a higher level of abstraction than they otherwise would have.
http://freegeek.in/blog/2010/05/clojure-protocols-datatypes-...
Yeah, but as long as they expect Callables in the right place interop can be pretty easy with just interfaces. For instance, you can pass JRuby lambdas to Clojure functions just fine. Sure there's a duplication of effort, but it's not too bad for interop purposes.
I beg to differ: http://github.com/technomancy/clojure-gem/blob/master/test/t...
Again, you cannot pass a ruby function expecting arguments to Clojure! What your link shows is that you can, however, send monkey-patched versions of ruby functions that implement clojure-specific calling conventions to clojure. :)
http://news.ycombinator.com/item?id=1257599
Good point regarding the effect on interoperability. I don't have an answer for that.
Oracle is ceasing to be the Ultimate Uncool Company in tech. (no, really, that place is Microsoft's - Oracle never stood a chance)
History, inertia, lack of any demonstrated interest or unified direction, key Java players running away, a change in planned features every month, no clear incentive, almost no interest from Java programmers? (What interest there is seems to be mainly from the fringe community involved in Scala and Clojure, who want invokeDynamic.)
Wanna bet those are never going to make it in Java7?
Oh wait ... probably some half-baked form of those will ... after all, they are calling anonymous method blocks that DON'T capture the whole current context "closures".
Not to mention that they could've inferred the type of the requested function ... an instance where those half-baked generics could've actually been somewhat useful, instead of just a way to avoid explicit type-casts.
The whole language is fucked-up. They should've just froze it at version 1.4 and be done with it.
edit: Actually, now that I think about it, this wouldn't be the first time they introduced a new keyword with a language update. So much for that argument:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_k...
That proposal also used the "#" symbol, with the following rationale: "The symbol is already used within Javadoc to separate the class name from the method name in exactly this manner. The method literal syntax merely brings the Javadoc convention into Java source code."
It's a reasonable choice for full first-class methods; it doesn't fit quite as nicely if Oracle only introduces closures as a syntax sugar for anonymous classes.
But I think it's OK anyway -- it's concise and even looks a bit like clojure :-)
E.g.,
public class Ref<T> {
private T t;
public Ref(T initial) { t = initial; }
public T get() { return t; }
public void set (T t) { this.t = t; }
}
public Callable<Integer> makeIncrementer(int initial) {
final Ref<Integer> ref = new Ref<Integer>(initial);
return new Callable<Integer> () {
public Integer call() {
int rv = ref.get();
rv += 1;
ref.set(rv);
}
}
}
Nonetheless if the reference closed over still has to be final (e.g., I can't just give it an Integer) this is merely syntactic sugar over what Java already has. Perl had this for ages: sub make_incrementer {
my $i = shift;
return sub { return $i++; }
}
Too little, too late. I am almost certainly using Scala (or Clojure) for any future JVM projects (unless there's a good reason not to).And for that matter, are they receptive to Clojure?
Our customers are mostly fortune 1000 companies, the people we deal with are not very technical and almost always outsource all of their development work overseas. They're also very good at finding outsourced developers with minimal skill sets. So a language with a smaller pool of developers would probably be seen as a negative.