I’ve been quietly following the proposals and discussions on closures and other possible changes to the Java language, and the subsequent backlash suggesting that they’re a bad idea and Java should instead be frozen (and that we should therefore look to other languages for such things, or do them in a new “next generation” Java).
On the whole I’d be happy to see Java get closures and some of the other proposed features. I can already see one particular use for closures in my unit-test code. Some of the other proposals also have considerable appeal. But I’d only want these changes if they can be done in a reasonably clean and appropriate manner. It needs to be in keeping with the spirit and feel of the language, and it mustn’t add too many complications to everything else. There are already more than enough complications in the language, and each new addition just multiplies their interactions, corner-cases, exceptions etc. There’s probably a limit to how far one can stretch a language before it “jumps the shark”, and to my mind the addition of generics and annotations has taken us right to the very edge of that limit. The Ovid quote “Add little to little and there will be a big pile” also comes to mind.
So whilst I want closures and other such features in principle, I’m very skeptical about how this would work out in practice, and I’ve got a lot of sympathy for the “no more changes” argument (or at least, “no more major changes”). There are, after all, always other languages if you need something radically different.
But from my own point of view, Java’s built-in libraries and APIs are even more important than the language itself. The strengths and weaknesses of these libraries and APIs are a huge factor in how easy or hard it is to do anything in Java, and they play a big part in how we think about problems. There’s also a vast amount of code in there, and vastly more code built on top of them. So I think it’s actually the libraries and APIs that need attention, more than the language itself, and that should be the starting point for deciding how to proceed.
When Java first appeared, its built-in libraries and subsequent JCP-endorsed APIs seemed a fundamental improvement on the libraries of previous languages. A decade or more later, many are showing their age and they are collectively getting rather creaky – they’ve accumulated an awful lot of cruft, overlap, obsolete design, inconsistencies, deprecations etc. The newer APIs tend to be rather different to the older ones. There have also been dramatic changes in the nature of the problems we’re tackling and the environment we’re working in. It’s also far more practical to have community involvement in such efforts than it was in the past. And of course, we have a decade’s worth of experience and lessons from using and evolving this set of libraries and APIs.
So maybe the time has come to take a clean sheet of paper, be very brave, take a deep breath, and start afresh. Not just to replace or improve specific APIs (in the manner of JSR 310 Date and Time API), but to re-think the libraries and APIs as a whole – including which things we need APIs for, and what their scopes and boundardies are.
This could also include, for example: standardizing the approach to providing, locating, intializing, configuring and using “services” of any kind; separating out anything else that’s common across multiple APIs; adopting a consistent approach to argument validation, error handling and error messages; making sure the APIs don’t hinder the testing of client code; taking full advantage of the latest language features etc etc.
Now that’s an absolutely huge undertaking, but it’s no worse than would be faced by any entirely new programming language. Maybe this is just a normal 10-15 year cycle – the libraries evolve over a decade or so, but eventually become so cumbersome and outdated that starting afresh becomes the best way to relieve the various pressures and move forward.
Once you start thinking in terms of a fresh new set of libraries and APIs, it becomes worthwhile to clean-up and enhance the programming language as much as possible first, so that you can take full advantage of this in the new libraries and APIs. For example, it might be helpful to get rid of primitives and arrays so that the new libraries can deal purely with “normal” classes, and to have closures, reified generics, maybe explicit support for properties and events, and a better approach to modularization/versioning right from the start.
Conversely, the JVM still seems absolutely fine, and Java in general has been hugely popular and successful and has a mass of people familiar with it. At any rate, I for one still like it! So something that is based on Java and running on the JVM would seem a much better bet than starting completely from scratch.
And if there were a new language based on Java but cleaned-up and incorporating new features such as closures, and positioned as being a “next generation” Java, then there’d be less pressure to squeeze all sorts of extra features into the existing Java language.
All of which suggests that my preferred route forward would be:
- Maintain the existing Java language without major changes (not necessarily “frozen”, but don’t bother trying to introduce anything major or controversial like closures).
- Develop a new “next generation” Java language. Take Java as its starting point and try to keep to the spirit, feel and syntax of Java, but simplify and clean-up the language as much as possible, and then incorporate any desired major enhancements like closures, reified generics, better modularization/versioning etc (whilst not going overboard with this – it still needs to feel like Java, not become too complex, and not tread too far off the proven path).
- Make sure the new language has some reasonable way to still use the old Java libraries and APIs, maybe through some kind of “compatibility” layer if necessary. This would make it possible to start using the new language without first having to complete the development of an entire set of new libraries and APIs first, and provides a reasonable migration path.
- Progressively develop a completely new set of libraries and APIs for the new language, taking full advantage of the new language and the lessons we’ve learnt from Java’s libraries and APIs, and focused on modern requirements.
Of course, I’m just an ordinary punter, with no particular qualification or authority to speak on this matter, or any realistic way to get it done. I’m also not faced with having to solve the many problems it would raise, nor fund all the work that would be involved!
But that’s my own personal view on how I’d ideally like to see things evolve – I still like Java, but I’m ready for a new version that breaks with the past and has its own newly-designed libraries and APIs.