Java is an excellent example of how you start out with a design that is rather “impure”, and has to be, in order to survive the initial competetive struggle; and then later, when there would be enough resources to realize some of the Real Cool ideas, you realize you can’t because you’re stuck with what and how you started.
One such example is the handling of primitive types. Auto-boxing is just a hack, trying to introduce “Everything Is An Object” through the back door. But the special cases introduced in the beginning stay in place.
A more recent example is the closures for Java / CICE discussion, where everyone agrees it’s going to be an addition to the Java language; no way you could replace some old feature made redundant by the new stuff. You cannot even extend the existing interfaces, because that would break implementations of those interfaces that exist out there in the wild.
There are fundamental decisions that cannot be changed easily once people have started building upon them. Operating Systems, Programming Languages, Platform APIs, Off-The-Shelf Software, they all have more than just a little legacy compatibility problem. The current anti-intellectual “agile” trend is good enough for applying those flexible, mature and well-thought-out processes and tools, but trying to develop and maintain a programming language in such a light-footed way means asking for desaster (or at least, bad quality).
A platform won’t stay competetive for long if you bolt on new things where they get in your way. If Saint-Exupéry is right, you need to remove things to increase consistency, making the language and platform more understandable and more usable.
The way to save your investment is to modularize, parallelize, interoperate, and deprecate. You can’t take things away from the Java platform, but you can provide increasingly consistent alternatives for parts of it (“nio”), interoperate with the old stuff for the time being, and hope for the old stuff to fade away. Note that this is not an agile approach – it does not involve a closed world assumption, it aims to keep long-term promises, and it ties significant resources (for maintaining several alternatives plus interoperability between them). Agile projects do not have a history; platforms do.
Most parts of Java will be with us for years to come. So please, don’t spoil the Java language and syntax with a mix of redundant, overlapping, complex features; don’t add something you may want to remove later. If it’s not proven yet, it doesn’t have to be part of the platform; just provide the hooks for others to provide it and experiment with it. I’d rather have a mix of language environments that Play Well With Others, with a JVM that acts as a “Common Language Runtime”, than a monolithic superplatform that assimilates every feature under the sun.