6 ms·
Java 7: Oracle pushes a first version of closures
- strebler 16y agoLook at what the cat dragged in - a syntax for closures in Java.
- RodgerTheGreat 16y agoWe've been calling them "anonymous classes" for years.
- jimbokun 16y agoAnd we've been needing a usable syntax for anonymous classes for years. 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.
- RodgerTheGreat 16y agoI can see that, but I'd be a lot happier if the new syntax they came up with was more consistent with the rest of the language. 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.
- rictic 16y agoIt is ridiculous. 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.
- orangecat 16y agoJava 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. 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.
- deleted 16y ago[deleted]
- DrJokepu 16y agoCompare that to how you would do it in C# (note that's not how you do comparisons specifically, this is just to demonstrate the C# lambda syntax): list.Sort((i1, i2) => i1.CompareTo(i2)); Isn't that an awful lot more readable / usable?
- bfung 16y agoYes, actually, while I was editing, I was going to mention C# delegates and new lambdas (I've been using C# 2.0, haven't upgraded yet). In my opinion, C# has been the better Java for a while; I think they should just copy C# stuff since it's already been proven to work and has some nice properties/syntax. It's not like C# didn't copy from Java in the earlier days...
- viraptor 16y agoThere's nothing unusable about it (by definition). But wouldn't: \(Integer i1, Integer i2) { return i1.compareTo(i2); } be nicer? (or whatever else syntax) Redundancy is already pretty common in Java and the current syntax just seems to try to win the price for most redundancy. You're implementing one interface, which you can infer in most cases with one function which you already know, which returns one result you already know the type of. So why would I want to repeat that? Sure - you can use the verbose syntax when you have many methods, but this example could be cut down to one line. Less line noise -> less errors.
- bfung 16y agoApologies: was editing, deleted, but people already replied; I always forget the markdown syntax... 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?
- whakojacko 16y agoyea, that looks about right. Everyone looking for these kind of features should probably just be using Scala...
- ericlavigne 16y agoWhile I would prefer Scala over [Java + closures], and would prefer Clojure over either of those, I am still pleased to see closures in Java for several reasons. 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.
- technomancy 16y ago> 2) Currently each JVM language has its own incompatible reinvention of closures. 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.
- sreque 16y agoHow in the world do callables replace closures? Closures can have arguments, callables can't. You cannot pass a ruby lambda expecting arguments to Clojure.
- technomancy 16y ago> You cannot pass a ruby lambda expecting arguments to Clojure. I beg to differ: http://github.com/technomancy/clojure-gem/blob/master/test/test_ref.rb#L46 http://github.com/technomancy/clojure-gem/blob/master/test/t...
- 16y ago
- sigzero 16y agoMaybe they are trying to make Scala the default language on the JVM with that? :-)
- bnoordhuis 16y agoThe syntax won't win beauty pageants but I like how they retrofitted lambdas onto interfaces so you can do something like: Collections.sort(list, (Comparator) #(String a, String b) { return a.compareToIgnoreCase(b); });
- lzimm 16y agodude, you made it look so much prettier than those examples
- jpr 16y ago(sort list #'string-lessp) still wins in my book :)
- deleted 16y ago[deleted]
- jimbokun 16y agoYou can always static import Collections.sort. The main thing missing, then, is a way to simply refer to an existing method to perform the comparison. Is there syntax for this in the current release? (I believe there was in some of the earlier proposals.)
- tlrobinson 16y agoI haven't tried this but according to the comments on the post you can do something like this: Comparator string_lessp = (Comparator) #(String a, String b) { return a.compareToIgnoreCase(b); } sort(list, string_lessp);
- jpr 16y agoYeah, but that just seems wrong. It's like "I have this function, but I can't actually refer to it, so I'll have to wrap it in this thingamajig just so that I can pass it around".
- morphir 16y agonow the blob-programmer can create compound blobs out of smaller atomic blobs.
- pivo 16y agoYou mean "blub", right? Anyway, as someone stuck programming in Java because our customers require it I would welcome this language addition.
- wglb 16y agoOut of curiosity, how flexible are your customers to updating java versions? And for that matter, are they receptive to Clojure?
- morphir 16y agousually its the jvm that is the dependency. So I don't see why you could not program in clojure or scala.
- sigzero 16y agoYou could but the talent pool is much smaller for both of those and the customer might not like that.
- pivo 16y agoWe could but it would be difficult. Our product requires that our customers subclass our Java classes to implement their custom business logic, and sometimes it's necessary to provide the source to our base classes for reference. Sending a customer some Clojure code and expecting a Java developer to know how to handle that doesn't seem reasonable.
- morphir 16y agoone can also ask the question whether its you that want to continue coding in java, because you think in java, or because you want to avoid learning something new. But yeah, if the customer don't grasp Lisp, you are pretty much settled with java.
- jared314 16y agoGood or bad, I am just happy they are actually doing something. (Wow, that is depressing.)
- radu_floricica 16y agoI _really_ didn't expect to say I love Oracle. But in hindsight, better productivity for the Java platform is a huge thing for them.
- deleted 16y ago[deleted]
- rbanffy 16y agoIt's like watching your hero being swallowed by a monster and then discovering the monster started to exhibit some personality traits of your hero ;-) Oracle is ceasing to be the Ultimate Uncool Company in tech. (no, really, that place is Microsoft's - Oracle never stood a chance)
- euroclydon 16y agoWhat's with the "#" sign? Is that new for lambdas, or an existing Java symbol?
- ebiester 16y agoThat's new for lambdas.
- tlack 16y agoJava isn't very "symboly" in practice. Any idea why they made such an unusual choice? I'm not against it (I prefer symbols to long words generally, even if they have a slightly longer learning curve), but it seems unlike the rest of the Java spec.
- RodgerTheGreat 16y agoWell, the alternative is adding a new keyword, and it's difficult to do that without risking breaking any existing code that uses whatever identifier they choose. Breaking old code is even less "Java" than introducing new symbols. 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/_keywords.html http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_k...
- deleted 16y ago[deleted]
- bokchoi 16y agoIt's borrowed from the javadoc syntax, unfortunately.
- svv 16y agoThis syntax is similiar to Stephen Colebourne's FCM proposal: http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc 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 :-)
- BonoboBoner 16y agoGood to know that they at least work on it and dont delay it till jdk8. This will be a great addition to the jdk for alternative-language-developers just like MethodHandles allowing them to compete with Java performance-wise.
- WilliamLP 16y agoI think waiting for Oracle to do something with Java 7 at this point is like believing Lucy will let you kick the football this time.
- avar 16y agoIs there anything to suggest that they'll let the current development hell continue? They have a lot invested in Java now, they might actually get their act together and push Java forward. Both to make it attractive to the programmers that like C# better, and to add features to the JVM to allow alternate languages to thrive, e.g. tail-calls and coroutines.
- WilliamLP 16y ago> Is there anything to suggest that they'll let the current development hell continue? 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.)
- bad_user 16y ago> tail-calls and coroutines 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.
- zmmmmm 16y agoI don't know why you say that. Oracle is brand new on this turf. There has been no chance of kicking any footballs under their watch yet. They deserve a chance to prove whether they're good or evil without prejudice here.
- jrockway 16y agoNone of these closures actually close over any state. Is that feature going to exist, or are these really just C-style function pointers?
- strlen 16y agoIf this is equivalent to anonymous classes, then it can close over final references. 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).