So it's confirmed. Despite James Gosling wanting closures, despite 3 working closure prototype compilers, despite every other JVM language supporting closures, Java 7 will not have closures.
while (true)
print("new Runnable() { public void run() { ")
Frankly, I'm pissed off. I'm sure Java dying will kill the JVM too, ultimately.
In the meantime, there's Scala. But the Java community will probably prefer Groovy, because it has learned from Java that types are hard.
(my source: http://twitter.com/theplanetarium via Ismael Juma)
36 comments:
While I share your melancholy, I don't agree with your prediction regarding the JVM.
I think I can summarize the JVM as the best assembler (ever!):
1) It is object oriented
2) It is platform independent
3) It checks for all sort of mishaps that are so typical in low-level programming. I am *not* speaking about type checking. I am speaking about ensuring that parallel execution paths are balanced, that the stack is empty at the end of the method. That sort of things.
4) Other goodies: concurrency, security, etc.
I feel it's the best platform for making languages, components, programs, talk to each.
Do you think that with Java no longer making advances, the JVM will continue to do so?
Point 1 is actually a disadvantage. OO is a problem.
Oh Yes, I forgot that you are an FP fan :)
Without ignoring the advantages of FP in all sort of domains, I think that interoperability across language boundaries is easier when the main abstraction mechanism is the object rather than the function.
It is easier to implement an immutable language that compiles to the JVM than it is to implement a mutable language that compiles to an FP-based virtual machine. I think the same goes for encapsulation.
I don't know of a specifically functional virtual machine, but I expect it would support monads, and that an imperative language would be compiled to monad uses.
I like FP because it does not have OO's problems. The function is not the only unit of abstraction though, there are datatypes in FP too.
Brian Goetz and Alex Buckley just gave a great JVM talk about... they seem to have a lot of features lined up to be added (including tail call and possible call/cc), and Mark R. verified in his talk that the invokeDynamic JSR will be in Java 7. Perhaps the JVM enhancements aren't the ones you want (focus is dynamic languages), but it's hard to say the JVM will die. More info on Mark's Java 7 talk here: http://hamletdarcy.blogspot.com/2008/12/java-7-update-from-mark-reinhold-at.html
Hamlet,
I don't doubt that the current bunch of JVM improvements are good ones. My favourite JVM language, Scala, can benefit from all of them, even without being dynamically typed.
I expect that if Java doesn't keep up with the languages around it, the ecosystem will suffer. The JVM will get less funding and less attention, because normal Java developers won't see their applications go faster with optimisations intended for better languages.
I doubt that the CLR would be as good as it is if C# hadn't evolved since version 1, for example. It probably would not have optimisations for generics, for example.
I very much doubt that Sun will reduce funding for the JVM just because Java is not keeping up with the languages around it.
Of course, having Java as a driver for new JVM features helps, but it's not a requirement as we've seen with the invokedynamic JSR. After all, Sun is also backing JavaFX Script, JRuby and Jython to name a few.
Finally, most of the interesting JVM-level improvements are performance-related and all languages will benefit from them (including Java). There is enough stuff there to last for several years and the fact that Java doesn't have things like value objects and primitive specialisation for generics increases the need for optimizations at the JVM level.
In twenty years of software development I never suffered the absence of closures.
But I really suffered from missing functions in the standard libraries, from quick-and-dirty coding of others and in the last years even from unstable IDEs and incompatible libraries.
Our customers are not interested in closures - they aren't interested either in object orientation. What matters to them is costs, reliability, security, ROI and such things.
Although I find closures nice offering nice features I currently do miss a practical sample where I would now go to implement it using closures. Further I do have security concerns. I don't know details on how closures are implemented in the prototypes but I imagine there could be possibilities to introduce malicious code with the use of closures.
Please remember where the focus should be. I do not think that closures are so important.
Martin,
Consider the following C#:
var onlyTheImportantCustomers = customers.Where(c => c.Value > 150);
if (interestedInFirstOnly)
{
. . Console.WriteLine("The first important customer is " + onlyTheImportantCustomers.First());
}
This doesn't look amazingly different to Java code and you could easily do it using a loop. The difference is that Where is lazy - if you only consume the first element the rest are not computed.
There are an absolute ton of examples; this one was just fresh in my mind. The equivalent Java would be painful.
Martin,
It was just yesterday that I read this post: http://arantaday.com/blog/the-power-of-the-functional (which, BTW, I made there a comment regarding readability of FP code).
It's really hard to estimate the ROI effect of a language feature. Nonetheless, it seems that higher level constructs do promote productivity.
Martin,
I forgot to reply to part of your comment.
In all 3 closure prototypes, closures do not add any possibility of malicious code, as they compile to ordinary Java .class files, which are checked for vulnerabilities by the JVM's verifier.
Oh well, this was expected no? Sun left Java itself behind for JavaFX no matter what Sun marketing people will have you believe.
Hmm perhaps it's time to get C# working on the JVM. Also, do you completely rule out Fan?
Casper,
I rule out Fan. It supports using generic types but not defining your own. As such it's 'annoyingly-typed'.
Here are my requirements for a programming language (other than for toy problems like configuring emacs): Generics, lambdas, recursion.
Although I do not really understand the gain of closures in your previous sample I can imagine (and searched the internet for a few samples) cases where it saves you from writing some lines of code - maybe with the cost of readability.
You mentioned in an earlier blog post that closures already exist in Java (see Why Java Needs Closures (It Already Has Them)) so we are neither talking about a completely new feature (another reason why the title of this post is IMHO completely exaggerated).
Anyway here are a few good examples of the advantages of closures: Closures Syntax in Java 7
I tried comparing the readability and as I am not a Java expert I find the non-closure versions easier to understand (from the time I have to look at them before thinking to understand what exactly happens).
I am also trying to avoid the usage of anonymous inner classes in my code as I find them not very clear and readable in general. - Talking generally I do prefer writing a little bit more lines improving the ability to maintain and enhance later. Also from the debugging point of view it is more efficient then.
If you don't understand the gain of closures in my example, please show the code I showed, written without closures. I think we'll both agree that it is not as readable.
Yes, technically Java has had closures since 1.1, and arguably since 1.0 (method bodies can access fields). A better term for the proposed feature for Java 7 is 'lambdas', but for some reason 'closures' was generally used instead. I stuck with the usual use for this blog post.
I don't think that examples page is actually BGGA or any other proposal's syntax, at least not throughout.
About writing more code, would you say that repetitive code is better than unrepetitive code?
"saves you from writing some lines of code - maybe with the cost of readability."
Are you drawing a parallel between amount-of-code and readability? I don't think that's necessarily the case - especially not when nesting is involved which happens a lot in Java.
Composability has always been paramount to programmers, it's how we raise the abstraction level and achieve better code reuse. If you've ever done Swing programming, you will recognize how it does not make for greater readability to constantly wrap your code in:
EventQueue.invokeLater(new Runnable() {
public void run() {
// Actual code
}
});
No, I don't want to draw a parallel that more code means better readability. Surely this is not necessarily the case.
Regarding the invokeLater I would write a class
public class MyBatchProcess implements Runnable
{
public void run()
{
//Doing my stuff
}
}
[...]
EventQueue.invokeLater(new MyBatchProcess()
Martin,
Your MyBatchProcess, if it requires information that was available in the method that uses it, requires data to be explicitly passed around. This seems an odd choice when the language can do it for you.
But it occurs very seldom that I need a piece of code only once at a particular position. In most cases I do reuse my code pieces.
But I think we get slightly off-topic.
Martin, this is where it starts to fall apart little by little if you ask me.
You have now used up that interface signature, and it won't help you very much to try and take advantage of generics, say implement both Comparable[T] and Comparable[U].
Feel free to be bummed, but the whole sturm and drang over language features is pointless. Readability is nice, conciseness is nice, closures are nice, yeah. But the only language feature of the last 20 years that made a revolutionary difference to code quality was Java's marrying of garbage collection with OO. All the other stuff is nice, but makes really tiny incremental improvements. Remember, except for fanboys, the important thing is how well your product works and how fast you were able to build it. You might build it a little bit faster with closures, or better generics, etc., but none of them will match GC for impact. At this point, most language features are akin to arguing about the relative shape of pencils -- those round ones are nice, but the hexagons don't roll. Misses the point that they both write.
So Java 7 won't have closures. Java has survived a decade without closures. C and FORTRAN have survived decades without closures. What makes you think it will suddenly now that it doesn't have closures?
Closures are controversial. It's basically trying to fudge another paradigm into Java--C++ should have taught us that a One Language to Rule Them All doesn't work.
For about 95% of programmers, closures will be hard to read, hard to write, just plain confusing and ugly. Generics in and of themselves are quite confusing, but there is a large useful subset that just works.
Also, don't be proud about having 3 working prototypes. That means you have 3 different, incompatible versions.
If you talk to many professional developers, you'll find that most of them are not particularly interested in closures.
Being a developer, I have to say I would use closures A LOT. I desperately NEED them. Most if those developers coding against frameworks like Swing (invokeLater()) would agree.
As an architect, I have to say that building architecture that uses anonymous classes a lot (Transaction.execute(Runnable), JDBC.call(Runnable), Auth.runAs(...), etc), is confronted with confused and annoyed developers saying thay hate the redundant and ugly:
String result = Tx.execute(new Tx[String]() {
public String execute() throws SomeException {
return "hey!"
}
});
Problem is, most of them are unaware the could do better:
String result = Tx.execute({ return "hey!"; });
(Anyway, I don't think Java just died nor it is dying. It has some problems, sure. But there's still great potential.)
@anonymous:
> the important thing is how well
> your product works and how fast
> you were able to build it.
Indeed, that's what I say also. IDE and available libraries (components, frameworks, utility function collections etc) are contributing a lot here, not only the GC.
@patrikbeno:
> String result = Tx.execute({ return "hey!"; });
What I noticed learning Java is that an important question always is "What is it?" - in the meaning of "What type?" or "What's it's result?"
In your sample the part within the closure does not describe it. It looks like a piece of JavaScript inserted into a Java application. It either does not declare possible exceptions.
I am sure that especially for using anonymous classes closures would help a lot. But I don't like them and avoid them if possible. Just compare some code created by the Eclipse Visual Editor with code created by the NetBeans Matisse. The latter does not produce those bulks of anonymous classes and the code looks much clearer.
But I agree with you that there are several annoying things that could be "solved" with closures. But then we should also start looking at exception handling and other things which I find annoying...
It's a good thing that I jumped ship this past summer.
Java is dead. Long live Java... I mean... Groovy.
WAHHH! Cry to mommy.
Actually, the interesting thing about Devoxx this year was not that the Java language felt dead, but that it felt alive again after 3 or 4 years of relative silence. I had no expectation that 'closures' would be included, and many of those I spoke to remain very sceptical of many parts of BGGA. What is interesting is that there will be small language changes in JDK7, and that is news and will help fixup some of the minor pain points that affect developers.
Well, there is no way a language with this much use can die. C++ and VB6 and Cobol are all doing fine.
Not too much new development is done in those languages, though. But the JVM will have to exist as long as the language needs support.
Of course having closures in Java 7 would be cool, but I much prefer to have other (planned) features in Java 7 than just one BIG "next cool thing". Plus some people are already saying that the platform is too huge, I wonder what they would have said with closures added in Java 7 ;-)
Plus I'm not really sure that having closures would be really a huge improvement for the platform (even if I like the idea).
Java 7 is dead, long live Java 8. At least we can hope to get type annotations as @ReadOnly or @NotNull in Java 7.
The posters here have really limited language experience and tend to post total bunk.
Smalltalk = OO + GC. Java was no pioneer here.
Closures are simply a very NATURAL way to write programs. At a very, very primitive level, think of C's sort() routine. More canonically, think map(), foldl(), foldr().
As for "customer demands," customers don't give a hoot whether or not you use BASIC. Customers don't care whether or not there are local variables. In other words, except for a small number of sophisticated customers, customer options matter NOT ONE LITTLE BIT when it comes to language features.
Sheesh. The level of dialog could use a major upgrade here.
Oh, and lack of functional features may well kill off the JDK. I write compilers. I need algebraic data types representing AST's. I need to walk whole translation units of AST's RECURSIVELY, conducting rule based rewriting. Without tail recursion, my code is likely to die a horrid death. Similarly, closures allow me to add new "first class" rewrite rules dynamically.
Gosh, sounds like I should migrate over the F# on the CLR (and I'm NOT MSFT lover).
Get clueful Sun!!!! Before it's too late.
> Gosh, sounds like I should migrate over the F# on the CLR.
That's exactly what Neal Gafter did. I get goosebumps sometimes thinking about what that design team is now contemplating of language goodies.
var onlyTheImportantCustomers = customers.Where(c => c.Value > 150);
if (interestedInFirstOnly)
{
. . Console.WriteLine("The first important customer is " + onlyTheImportantCustomers.First());
}
Written without closures (in Java style):
for(Customer c : customers) {
if(c.getValue() > 150) {
if(interestedInFirstOnly) {
System.out.println("The first important customer is " + c);
break;
}
}
}
Not too long, right?
You shouldn't ignore the Law of Leaky Abstractions here. For a person to understand that the closure-based version is efficient, he needs to know the internals of the list produced by Where (namely, that it's lazy-evaluated).
One could even argue that using overly high level of abstraction (in not-so-high level languages as Java) is a rather selfish act when working in a team since only you (and maybe 5% of highly devoted co-workers) will understand the resulting code.
Personally, I would take null-safe types over closures any day. Sure, anonymous classes are a nuisance to type, but unlike accidentally passing nulls around, they don't have a rippling effect on the correctness of the program.
Despite Ricky's hyperbole, it does appear that Java is going into "maintenance mode".
That's not necessarily a bad thing. The problem as I see it, is that you have only one viable statically-typed language on the JVM - Scala. And I don't think Scala will ever quite break into the mainstream.
I recall that on the Groovy roadmap, someone had put in an entry for statically typed Groovy - with a ? mark.
I don't see a dynamically typed language on the JVM ever becoming a successor to Java. There's a big tooling support problem, and with type inference and other things you can almost get that scripting feel.
Take a look at Boo. I wish the port to the JVM would get done already. It's a statically-typed language that allows for dynamic (duck) types, macros, python-like syntax, type inference, etc..
Boo on the JVM could be a successor to Java, but it would need funding.
Post a Comment