Why, There a lot of organizations that have allot of invested time, training and code-base in Java. Even if no new features where added to another Java application, adding closures to ease the maintenance of existing code is justifiable enough.
Like it or not Java is the enterprise language and Ruby, Scala, Haskel et.al. are not going to take that crown any time soon, just as it took Java a long time to supplant COBOL, one of them will have to grind it's way in inch by inch. The fact of the matter is that for what Java is intended for, it does a very good job so it is not in the same seat that COBOL was.
I dislike Java (from a personal enrichment perspective) as much as the next guy, but it is never too late to improve a language with such a useful feature, especially a language that is going to be the dominate language for the foreseeable future.
I'm experimenting with Go on a few personal projects and enjoying it; it grows on you and its good not to have to deal will objects all the time. But the experience (specially the performance) has made clear Sun's accomplishment in the Java language and the Java Virtual Machine. Current fad of dumping on Java will pass and history will be quite kind to Java (imo).
It is fast - but not significantly more than Haskell, C#, OCaml, etc.
Java is a terrible language though. For example:
-The syntax for doing anything remotely functionalish (anonymous classes, function currying, etc) is completely unwieldly.
-Null pointers still being a problem in 2009 is an embarrassment. A simple Maybe Monad would fix it (of course, because of previously mentioned syntax problems - I need the language implementors to add syntactic sugar since library-based Maybe Monads are too ugly.
-Generics and autoboxing were a good start at fixing the terrible type/primitive system, but Sun has proved unwilling to break backwards bytecode compatibility, which leaves us with ugly hacks like type erasure.
The JVM is undeniably impressive (and even more so once we get invokedynamic and tailcall bytecodes) and I think that is going to be the true legacy of Java. Scala, Clojure, et al show amazing promise - in a few years I could see JVM languages dominating the field.
Using "terrible" to describe Java is precisely what I meant by dumping on Java.
A terrible language is a useless language; something not worth using; terribly broken; more trouble than its worth. Just the sheer volume of quality work by non-commercial open source developers provides a resounding rejection of that notion.
Java is an imperfect, perhaps flawed (but not deeply) language. But I guess that would find it in good company with many great languages out there.
And yes, The JVM is an impressive technology. (And do note that it is the Java virtual machine and not the Sun Virtual Machine, given that (the latest welcomed opcode developments notwithstanding) it is a virtual machine designed and developed to provide support for the language that informs its computational model.)
"Terrible" is a subjective description, so I don't think there's any inherent contradiction between you calling Java "imperfect" and "flawed", and smanek calling it "terrible".
Generally speaking, it's very difficult to compare programming languages objectively. What one person might think is a flaw, another might consider a feature.
That said, I'm personally inclined to agree with smanek. There are a lot of design decisions in Java's syntax that are, to put it kindly, rather bizarre and perhaps not particularly well thought through. "Terrible" would be the word I'd pick as well, were I asked what I thought of Java's syntax.
Closures are a useful feature, but I'm afraid the current proposal is crippled ... and as in the case of generics implemented with erasure and some serious variance problems ... this will be a feature where the complexity added will outweigh the benefits.
The first problem ... apparently they aren't planing on adding capturing of non-final variables. This is a PITA since a lot of anonymous classes are using just that by boxing those vars in final arrays ... which is the kind of boilerplate I could do without, but I guess readability of code is not a priority (oh, the irony).
The second problem ... the proposal is not final, but from what I've seen the "Function type" has to deal with primitives, and they are going to do that through code-specialization ... and if that's the case, it would be yet another case where they are introducing exceptions in the language (like it's the case for arrays or for operator overloading). I'm not even going to mention the "special" syntax introduced for collections.
The third problem ... since we are talking about fork/join, it would be best to leave the constructing of the query to the designer of the framework, therefore returning the syntax tree of a closure (instead of the method refence) would be really useful. The proposal doesn't include such "futurist" notions though (LISP's quote is very cutting-edge after all).
The fourth problem ... it would be best to deprecate Java in favor of something else running on the JVM. But what chances would a language have that isn't totally different (in which case it would diverge from the type system, therefore slow or with interoperability problems) or that doesn't have feature-bloat to differentiate itself from Java (like Scala, which IMHO it's an abomination). The point being that adding features to Java makes life harder for everyone (including people using/developing other languages). Why not concentrate on advancing the JVM instead? Still no tail-calls, still no stack-allocated objects (with escape-analysis not delivering on its promise), and invoke-dynamic is one whole year away from being released.
And closures are a language feature that happened long before Java appeared, and it's been talked about it ever since the start. See this article about "Microsoft's delegates" ... http://java.sun.com/docs/white/delegates.html
Now they want to add closures because that's the only sane way to work with fork/join frameworks? No shit. It saddens me because it took a really loooooong time for them to realize this ... design by committee at its best.
>>> a lot of anonymous classes are using just that by boxing those vars in final arrays
final variables (primitive and references) will be accessible in the function literal, the proposal only states that 'capture of non-final variables' will not be supported.
What that refers to is the trick of transforming "int a;" to "final int[] a = {0}" and then referring to a[0] everywhere. This adds about 20 bytes of overhead on Sun's 32-bit JVM and memory pressure for almost no benefit whatsoever.
yes, but that syntax is unnecessary as the proposal allows for final variables (primitives and reference types) to be available in the function literal syntax
it is never too late to improve a language with such a useful feature
I have a different hypothesis. Every feature you bolt on decreases the learnability of your language, decreases the navigability of your documentation (the books are now 20% thicker, and the old books and web pages are now useless), and decreases the odds that two programmers who "know Java" can actually read each other's code.
It is also very hard indeed to introduce a new feature while preserving the functionality of existing code. The gyrations and compromises that are required are often enough to destroy most of the value of the new feature. Better to build a new system around the feature and let it shine, not struggle to fold a bastardized version of it into the old system.
The time to tinker with your system is when it is young. When the system is old, and people have already built their lives around it, it is too late to remodel the foundation. You can take this principle too far [1] -- it is important to enjoy your youth fully, not settle into premature senescence -- but any system which becomes popular will sooner or later reach maturity.
Eventually your codebase, installed base, community, and documentation reach the point where every time you change something important, you lose more in coherency than you gain in power. [2] At that point your system is mature. The best thing you can do at that point is to accept the facts of life and let the system settle into its role -- preserve the value of the work you've already done, the books and lectures you've already written, the people you've already trained; then build on that work by calling its APIs -- while working on a new system on the side. Because it is, in fact, often better to have two or three smaller, comprehensible systems with fundamentally different features and maturity levels -- Erlang for the telephone exchange, Lisp for the airline-schedule AI, PHP for the three-line CRUD web page -- than a gigantic system that is constantly remodeling to add more corner cases, like the Winchester Mystery House.
Of course, Java's designers have never believed this hypothesis, or they would have left well enough alone years ago.
---
[1] As in the legend of the "make" syntax, which supposedly remains broken because, by the time the designers realized it was broken, they already had ten users and felt it was too late to fix. Don't worry about the first ten users. By the time you have a million users, however, it might be time to start thinking about stability.
[2] Think: Windows. It's mature. It no longer seems to be possible to make major changes in the fundamental structure of that operating system. And that's not necessarily a bad thing, unless Microsoft insists on trying, spending billions of dollars and most of a decade and breaking a lot of existing infrastructure in the process.
I somewhat agree with you in that Java should have made bolder moves earlier on to provide some of these features and not lash itself to a bunch of backwards-compatibility cruft.
And maybe a bunch of language changes right now will muddy the water a bit - but as far as I can tell, most of the new language features in Java 7 will cut down considerably on boilerplate and unnecessary verbosity, which should go a long way toward making code more understandable, which will be a breath of fresh air.
If a little bit of altered syntax like what's being proposed is enough to make anyone's head explode, maybe they should reevaluate whether software development is really for them. And if your enterprise's codebase and culture isn't ready for language changes, nobody is going to force you to switch to Java 7.
Microsoft has made major changes and additions to the C# core language with every release even though it has nearly as many programmers as Java. And it's still attracting lots of new developers, so apparently the learnability is not a problem in practice (at least not yet).
For your critique to be useful, I think you need to say what are the superior alternatives to Java + Closures.
I'm betting that whatever language you propose, there will be some set of tradeoffs that make Java a better choice. That's why we have different languages.
Java is fast, has as many libraries as almost any other language, decent threading support, decent unicode support, garbage collection, runs almost anywhere without recompilation (compared to most other languages), and a good fraction of all programmers know it.
For most other languages I can think of, Java is superior in at least one of those aspects. (Those other languages are superior to Java in one or more aspects, too, which is my point.)
java is slower than C, so is java not good enough? Also, by saying that both have fewer programmers that know them is saying that you will try no new language.
Earlier you talked about trade-offs. There are trade offs, and java's big win is that it's so widely used. From a language perspective (programmer productivity, etc) both are far better than java.
In the absence of the ability to capture non-final variables, the proposal does not add closures to Java, only 'function-literal syntax' for specific use cases, or for the java community 'anonymous-function' is lieu of more verbose 'anonymous-classes'
The is a positive step, but the lack of control abstraction is a terrible shame. With control abstraction I could really cut down the boilerplate code.
22 comments
[ 6.6 ms ] story [ 87.7 ms ] threadLike it or not Java is the enterprise language and Ruby, Scala, Haskel et.al. are not going to take that crown any time soon, just as it took Java a long time to supplant COBOL, one of them will have to grind it's way in inch by inch. The fact of the matter is that for what Java is intended for, it does a very good job so it is not in the same seat that COBOL was.
I dislike Java (from a personal enrichment perspective) as much as the next guy, but it is never too late to improve a language with such a useful feature, especially a language that is going to be the dominate language for the foreseeable future.
Java is a terrible language though. For example:
-The syntax for doing anything remotely functionalish (anonymous classes, function currying, etc) is completely unwieldly.
-Null pointers still being a problem in 2009 is an embarrassment. A simple Maybe Monad would fix it (of course, because of previously mentioned syntax problems - I need the language implementors to add syntactic sugar since library-based Maybe Monads are too ugly.
-Generics and autoboxing were a good start at fixing the terrible type/primitive system, but Sun has proved unwilling to break backwards bytecode compatibility, which leaves us with ugly hacks like type erasure.
The JVM is undeniably impressive (and even more so once we get invokedynamic and tailcall bytecodes) and I think that is going to be the true legacy of Java. Scala, Clojure, et al show amazing promise - in a few years I could see JVM languages dominating the field.
A terrible language is a useless language; something not worth using; terribly broken; more trouble than its worth. Just the sheer volume of quality work by non-commercial open source developers provides a resounding rejection of that notion.
Java is an imperfect, perhaps flawed (but not deeply) language. But I guess that would find it in good company with many great languages out there.
And yes, The JVM is an impressive technology. (And do note that it is the Java virtual machine and not the Sun Virtual Machine, given that (the latest welcomed opcode developments notwithstanding) it is a virtual machine designed and developed to provide support for the language that informs its computational model.)
Generally speaking, it's very difficult to compare programming languages objectively. What one person might think is a flaw, another might consider a feature.
That said, I'm personally inclined to agree with smanek. There are a lot of design decisions in Java's syntax that are, to put it kindly, rather bizarre and perhaps not particularly well thought through. "Terrible" would be the word I'd pick as well, were I asked what I thought of Java's syntax.
The first problem ... apparently they aren't planing on adding capturing of non-final variables. This is a PITA since a lot of anonymous classes are using just that by boxing those vars in final arrays ... which is the kind of boilerplate I could do without, but I guess readability of code is not a priority (oh, the irony).
The second problem ... the proposal is not final, but from what I've seen the "Function type" has to deal with primitives, and they are going to do that through code-specialization ... and if that's the case, it would be yet another case where they are introducing exceptions in the language (like it's the case for arrays or for operator overloading). I'm not even going to mention the "special" syntax introduced for collections.
The third problem ... since we are talking about fork/join, it would be best to leave the constructing of the query to the designer of the framework, therefore returning the syntax tree of a closure (instead of the method refence) would be really useful. The proposal doesn't include such "futurist" notions though (LISP's quote is very cutting-edge after all).
The fourth problem ... it would be best to deprecate Java in favor of something else running on the JVM. But what chances would a language have that isn't totally different (in which case it would diverge from the type system, therefore slow or with interoperability problems) or that doesn't have feature-bloat to differentiate itself from Java (like Scala, which IMHO it's an abomination). The point being that adding features to Java makes life harder for everyone (including people using/developing other languages). Why not concentrate on advancing the JVM instead? Still no tail-calls, still no stack-allocated objects (with escape-analysis not delivering on its promise), and invoke-dynamic is one whole year away from being released.
And closures are a language feature that happened long before Java appeared, and it's been talked about it ever since the start. See this article about "Microsoft's delegates" ... http://java.sun.com/docs/white/delegates.html
Now they want to add closures because that's the only sane way to work with fork/join frameworks? No shit. It saddens me because it took a really loooooong time for them to realize this ... design by committee at its best.
final variables (primitive and references) will be accessible in the function literal, the proposal only states that 'capture of non-final variables' will not be supported.
final int a = 0;
is all you need in the example you provide.
For instance you may want "a" to be mutable, but you also want to use its value when the closure gets executed.
I don't think I've ever used a framework in Java that relies on event-handlers / callbacks where I didn't had to box local variables.
I have a different hypothesis. Every feature you bolt on decreases the learnability of your language, decreases the navigability of your documentation (the books are now 20% thicker, and the old books and web pages are now useless), and decreases the odds that two programmers who "know Java" can actually read each other's code.
It is also very hard indeed to introduce a new feature while preserving the functionality of existing code. The gyrations and compromises that are required are often enough to destroy most of the value of the new feature. Better to build a new system around the feature and let it shine, not struggle to fold a bastardized version of it into the old system.
The time to tinker with your system is when it is young. When the system is old, and people have already built their lives around it, it is too late to remodel the foundation. You can take this principle too far [1] -- it is important to enjoy your youth fully, not settle into premature senescence -- but any system which becomes popular will sooner or later reach maturity.
Eventually your codebase, installed base, community, and documentation reach the point where every time you change something important, you lose more in coherency than you gain in power. [2] At that point your system is mature. The best thing you can do at that point is to accept the facts of life and let the system settle into its role -- preserve the value of the work you've already done, the books and lectures you've already written, the people you've already trained; then build on that work by calling its APIs -- while working on a new system on the side. Because it is, in fact, often better to have two or three smaller, comprehensible systems with fundamentally different features and maturity levels -- Erlang for the telephone exchange, Lisp for the airline-schedule AI, PHP for the three-line CRUD web page -- than a gigantic system that is constantly remodeling to add more corner cases, like the Winchester Mystery House.
Of course, Java's designers have never believed this hypothesis, or they would have left well enough alone years ago.
---
[1] As in the legend of the "make" syntax, which supposedly remains broken because, by the time the designers realized it was broken, they already had ten users and felt it was too late to fix. Don't worry about the first ten users. By the time you have a million users, however, it might be time to start thinking about stability.
[2] Think: Windows. It's mature. It no longer seems to be possible to make major changes in the fundamental structure of that operating system. And that's not necessarily a bad thing, unless Microsoft insists on trying, spending billions of dollars and most of a decade and breaking a lot of existing infrastructure in the process.
And maybe a bunch of language changes right now will muddy the water a bit - but as far as I can tell, most of the new language features in Java 7 will cut down considerably on boilerplate and unnecessary verbosity, which should go a long way toward making code more understandable, which will be a breath of fresh air.
If a little bit of altered syntax like what's being proposed is enough to make anyone's head explode, maybe they should reevaluate whether software development is really for them. And if your enterprise's codebase and culture isn't ready for language changes, nobody is going to force you to switch to Java 7.
I'm betting that whatever language you propose, there will be some set of tradeoffs that make Java a better choice. That's why we have different languages.
Java is fast, has as many libraries as almost any other language, decent threading support, decent unicode support, garbage collection, runs almost anywhere without recompilation (compared to most other languages), and a good fraction of all programmers know it.
For most other languages I can think of, Java is superior in at least one of those aspects. (Those other languages are superior to Java in one or more aspects, too, which is my point.)
Both have significantly fewer programmers who know them.
Nice try, though. :)
Earlier you talked about trade-offs. There are trade offs, and java's big win is that it's so widely used. From a language perspective (programmer productivity, etc) both are far better than java.