17 ms·
Java finally getting closures, method handles and traits in JDK 8
- jburwell 16y agoYet another half-baked implentation of concept. Why in the world closures are limited to the SAM use case is beyond me. It's erasure all over again -- building a "general" purpose feature suited to one pratical use. It's no wonder that Java has lost its position as the platform on which to innovate and develop new projects. I wish Oracle would be willing to break backwards compatibility in JDK8, and deliver an truly innovative and exciting product. Guess I can wish for a visit from the Tooth Fairy too. * I make my comments as a Java veteran, and fan of the platform.
- Zak 16y agoThe innovation on the Java platform is no longer in the Java language but in other languages on the platform. Both JVM-specific languages like Clojure and Scala as well as JVM implementations of existing languages like JRuby are where people go for innovation these days.
- spullara 16y agoI definitely agree that Clojure, Scala, Groovy, JRuby etc are pushing the platform itself forward. InvokeDynamic is in JDK7 mostly for the benefit of dynamic languages on the VM and only in JDK8 will Java language features be dependent on it.
- spullara 16y agoPersonally I feel the choice was a good one. Closures (& method handles) will work out of the box with virtually every API in the JDK along with a tremendous number of APIs generated by 3rd parties. The type inference / coercion rules makes them very easy to use and possibly not as limited as you imagine. In combination with extension methods interfaces can be updated to work even more smoothly with closures and method handles without breaking libraries that provide or depend on those interfaces. I'll gladly take specific feedback on use cases that you think have been dismissed by the current proposal back to the expert group. Another question as I think they were unrelated. What kinds of features would you like to see in Java that would necessarily break backwards source compatibility? For example, I would like to see an 'auto' or 'var' keyword that is equivalent to the C++/Scala versions of same. Not a huge deal but would be nice. Thanks!
- raganwald 16y agoMy understanding is that the vast majority of Java development is done in shops where conformance to coding and pattern "standards" is valued as a way of allegedly making the code base easier to read and understand (I am not agreeing with this, just stating what I believe they believe). If my understanding is correct, which shop is going to allow people to start using these new techniques, when they already have a code base full of workarounds? Unless someone is going to sit down and refactor their humun-gi-normous code base, they will in effect be creating a second dialect of Java in their shop if they start using traits and closures instead of whatever they were already doing with Java's existing feature set. I just can't see this having any more than a token impact. Now Java users can say, "Sure we have closures. We don't use them here, but they exist and if we wanted to, we could use them. But we don't need them, so it's no big deal."
- spullara 16y agoI think the question here is whether or not it will defend against wholesale abandonment of Java to things like Scala and Clojure. To make the complete switch you might have to rewrite some code. With the Java improvements you can even keep a lot of your old code designed to work with inner classes and just use that code more effectively with the new closure and method handle syntax and implementation. There are many shops that probably haven't fully adopted generics from Java 5 in their own code but they benefit from the libraries that have moved to them.
- Sandman 16y agoWhy wouldn't they use closures and other new stuff in Java? It's the same like it was with generics - prior to 1.5 we used raw types with casting, but when generics were introduced we started using them instead. When you encounter some older code in your codebase that still uses raw types instead of generics, you just rewrite that portion of code. No problem with that. I mean, couldn't your point be made about any language that introduces new features? When that happens, do developers decide to rewrite the entire codebase? I don't think so.
- TeHCrAzY 16y agoDo you really rewrite working and tested code just to use new or more convenient features of the language? I don't see that being a good option, nor one that most developers would take.
- mark_l_watson 16y agoAm I the only person who does not care very much about future features until they are tested and released? Many thanks to the people working on new JSRs but I'll wait.
- colanderman 16y agoJava has had closures for years. Otherwise how would an anonymous inner class reference its parent's local variables? I suspect the author is confusing closures (a language implementation technique) with anonymous functions (a language feature which can be implemented using closures).
- stevoski 16y agoJava has had this since Java 1.1, I believe.
- skybrian 16y agoWhile it's true that anonymous inner classes implement a form of closures, among the folks talking about the next version of Java, "closures" has become the shorthand for the various proposals to improve the syntax for callbacks and/or add true anonymous functions.
- dcminter 16y agoDo you mean method local variables? Because if so it doesn't - it copies them and only allows you to reference them if they're declared final (const) for exactly that reason.
- colanderman 16y agoThat's exactly what a closure is. Keep in mind that the concept of a closure has been bred in the functional programming community, where variables aren't mutable. If you really need to reference a mutable variable in the enclosing scope, you can do in Java exactly what you can do in languages like ML/Scheme -- let the variable reference a mutable box (in Java, an object). The reference to the box (or object) is copied, not the box itself. In fact, in Java you can go one step further and just reference the entire enclosing scope by storing the parent's "this" in a final variable.
- DennisP 16y agoScheme has mutable variables, and introduced lexical closures in the 70's. You don't need any tricks with mutable boxes, you can just update an integer in the outer scope and it works fine. Scheme doesn't have an object system built in, but the closures make it easy to roll your own.
- deleted 16y ago[deleted]
- fingerprinter 16y agoBackground: I started programming Java in 1996 or somewhere around there. I was a huge advocate of Java over things like C/C++ for quite a long time and I believe in early 2000 it was the best choice. I no longer believe Java is the best choice for most projects as there are saner alternatives out there including Scala, Clojure and Jruby (for the JVM) and other languages/VMs altogether if you want out of the JVM. Bottom line: Java seems dated. Now, to my rant. import java.util.*; interface Sortable<T, U extends Comparable<? super U>> extends List<T> { void sortBy(Extractor<? super T, ? extends U> e) default Impl.sortBy; static class Impl { public static<T, U extends Comparable<? super U>> void sortBy(Sortable<T, U> sortable, final Extractor<? super T, ? extends U> e) { Collections.sort(sortable, #{T a, T b -> e.extract(a).compareTo(e.extract(b))}); } } } I HATE this code. This is an example of when Java went downhill to me and started to get really, really ugly. I always thought Java was verbose, but with generics and others things it started to get ugly. That was enough for me. I knew Python and Ruby and decided to go a different way. Found Erlang and Clojure started to mature on the JVM. Bye bye Java.
- kaffiene 16y agoI've been writing Java for a while now. I've never seen nor written code anything like that. Heavy use of generics is usually hidden away in APIs and don't usually occur in non-trivial ways in normal code.
- kujawa 16y agoYou mean code that was interesting to write, and not just another fucking web template?
- Jach 16y agoIt's not that much of a hyperbole... Map<String, Map<String, Map<String, Map<String, String>>> > meta_data = new LinkedHashMap<String, Map<String, Map<String, Map<String, String>>> >(); .... for (Map.Entry<String, Map<String, Map<String, Map<String, String>>> > schema : meta_data.entrySet()) { I really would rather just type: meta_data = {} .... for schema in meta_data.iteritems():