Version 3.0 of Python has been released. Notably Python has again done something Java has long resisted: it has broken backwards compatibility with Python 2.x. Notable fixes include a much saner string processing model based on Unicode. I am told by my Pythonista colleagues that a lot of other weirdnesses such as the print operator and the meaning of parentheses in
except clauses have been cleaned up as well. Though I don’t expect all Python programmers to upgrade immediately (and version 2.x will be maintained for some years to come) version 3.0 is clearly a simpler, better, saner language than version 2.x that will enhance productivity and make programmers’ jobs more fun. Bravo for Python. This is clearly a living, evolving language.
Java by contrast, is dead. It has at least as much brain damage and misdesign as Python 2.x did, probably more; yet Sun has resisted tooth and nail all efforts to fix the known problems. Instead they keep applying ever more lipstick to this pig without ever cleaning off all the filth and mud it’s been rolling in for the last 12 years. They keep applying more perfume when what it really needs is a bath.
Backwards compatibility was maintainable and useful through about version 1.4 of Java, but it completely broke down in Java 5 when autoboxing and generics moved the core language beyond any hope of comprehensibility. Autoboxing was a misguided effort to paper over Java’s early decision to have a segregated type system for primitives and objects. It was Java’s Plessy v. Ferguson decision that pretended primitives and objects were separate but equal; but the claim was no more true in Java than it was in American jurisprudence. A separate primitive type system may have made sense in 1995 when CPUs were slower and virtual machine technology was not as advanced. Today primitive types just complexify the language to no particular benefit. Autoboxing would not have been necessary or even considered were backwards compatibility not worshipped beyond all other gods.
Generics are another case where backwards compatibility took a good idea and warped it into something horrible. Multiple design compromises were made to enable genericized code to run in older VMs, most notably type erasure. Then, in the end, binary compatibility was broken anyway. However no one went back to the drawing board and considered how much simpler and more powerful generics could be if they redesigned without worrying about backwards binary compatibility.
Closures, if added now, would only make the situation worse. Closures might be a nice addition to the language if and only if Java simultaneously removed inner classes and made all other syntactic changes necessary to support true closures. Otherwise closures will just be generics squared. New features simply cannot be added on top of the current weak foundation unless we’re willing to go back to the drawing board and take things out as well.
I can’t think of another major language as old as Java that still attempts to maintain compatibility with version 1.0 of itself. In fact, I can think of only one language that attempts that (C#), and that one’s half Java’s age. Unless we’re willing to make the hard choices and abandon the legacy as Python has, Java is doomed to the fate of C++ and Cobol: a tool for programmers with long white beards who grew up with the language and have learned all its arcana by gradual accretion and who spend their lives maintaining code written a decade or more ago. Meanwhile a new generation of programmers will abandon Java in favor of more nimble modern languages like Python just as we abandoned C++ in our youth in favor of Java. (Seriously: is anyone under the age of 30 actually reading this site any more?)
Admitting that you have a problem is the first step to recovery. Java has not yet admitted that it has a problem. The language is too big, too complex, and too baroque. Trade-offs that made sense in the era of single core Pentium II’s, 100Mhz processors, and 32 megabyte memory spaces no longer apply. Backwards compatibility has become a millstone around Java’s neck. We’re deep and sinking fast. Until this millstone is cast off, and we correct the mistakes of the past, no further progress can be made.
It’s hard to believe that I first started saying this over five years ago, and absolutely no progress has been made in that entire time. In fact, matters have gotten worse. Maybe Java is a lost cause, and it’s time to fork and replace the language. If nothing else, Java proved that’s possible. Just look what it did to C++. Perhaps it’s time to repeat the experience.