Language lifecycle?

[this is perhaps mostly a social/marketing thought, please let me know if it is too far afield from LtU policies. I'm not trying to start a flame war, i'm only trying to study history and extract some lessons for it which might be useful to other language advocates.]

(I care about "success" of a language in the sense that a larger community might bring improvements to that language's ecosystem. Even just having the core system exercised by more people in more different ways is a benefit, for shaking out bugs.)

I think Java jumped the shark a long time ago. But people are bought into it enough that it keeps on chugging, even though it has clearly lost its "simple" origins. I think a similar thing happened with C to C++ because there were folks who were into the (relative) simplicity of C, and then moved along into C++ (just like people moved along into Java 1.4, .5, ... with all the complexity and incompatibilities introduced therein).

So I think one way (of many possibilities) to have a language "succeed" is to do a hard sell on the fact that it is simple vs. the other main-stream languages people use, and that simple is obviously better. Once you have people on board, then you can (and will be forced to by those same people, most likely) change it to become a more convoluted mess with not too many people jumping ship as a result; they're too bought in.

Is this good? I certainly think Java was useful in many ways, but I also certainly have a huge distain for how it has changed and become kind of insane - it seems to be heading towards the half-baked buggy implementation of CL event horizon.

So I'd argue that a refined approach would be to have your langauge:

  1. somehow designed to be revisable. Claims that you won't break compatibility either need to be backed up with real structure to support that, or you need to just not make the claim. Java kinda falls short there, methinks.
  2. "simple" in a really powerful PLT sense, as well as a "can i teach it to others" sense. Oddly, the folks who make Java knew full-well of real simplicity-with-power, but avoided it, presumably as another layer of pragmatism (with the obvious resulting success).
  3. So perhaps the real question I have in mind is: how to make something simple in the FP sense rather than in the imperative sense, and yet have it be be successful? (I believe Sun spent a lot on marketing Java, as an aside.)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Java compatability

Java kinda falls short there, methinks.

How so? IIRC correctly, there's nothing preventing a JDK1.0 program from compiling under the most recent Java versions, and if compiled their bytecode will still run. A handful of library methods have been deprecated (mostly for being really dangerous), but otherwise I'm unaware of any backward compatability issues. What am I missing?

OTing / Re: java version compatibility

I don't have a well defined list that breaks down the various kinds of forward/backward/sideways incompatibilities. I've run into issues myself with e.g. trying to use 1.5 classes on pre-1.5 VMs (or was it the other way around?). I've heard of Sun introducing new bytecode instructions. They have added keywords (assert).

Glancing around - these are not meant to be conclusive "i told you so" evidence, more just food for thought i've seen - Sun lists issues, apparently there might be issues with generics, things like plain-old-bugs happen when releasing a new version, or old bugs might haunt you, I think serialization is not guaranteed to survive, etc.

It might all come down to semantic games around what the words mean to people. I don't see Java as being internally compatible all the time. They've done a better job than most, probably, but it still has warts. Are there ways to design to avoid such warts, or to better handle the inevitability of them? Dunno.

Misunderstandings

1) Only backward compatability is promised, not forward. The only way to achieve full bi-directional compatability at the level you describe is probably complete language stasis.

2)No new bytecodes have been added since Java 1.0. One new bytecode is under consideration for JDK 1.7, invokedynamic.

3)Two new keywords have been added, assert and enum. If you used these as identifiers under earlier versions of Java, your code won't compile (although your compiled bytecode will run just fine).

4)There are many issues with Java generics, some of them quite infuriating, but backward compatibility isn't one of them. Indeed, the need to maintain backward compatibility is the cause of most of the issues with Java generics.

5)Bugs happen. The various Java releases have been incredibly clean as language implementations go.

Overall, Java compatibility has been much better than any other mainstream language, with the possible exception of Ada (Ehud?).

And yet 5 or so years on,

And yet 5 or so years on, we're only just getting to the point where requiring Java 1.5 is seen as a viable option. Many large businesses are still running on 1.4 and many open source projects won't use 1.5 features (or provide compatible replacements for the parts where they do use them) because of it.

I agree that in principle it's quite easy to migrate programs forward, but there are enough minor changes in behaviour that (particularly for large programs) this can introduce subtle bugs. Nothing a good regression test suite and test script shouldn't catch and allow you to fix, but nonetheless people seem to stick with the old versions. Often this isn't even their fault but because of something else they depend on which won't migrate - at work we've not been able to migrate our current application to 1.6, and there aren't even any language changes between 1.5 and 1.6! But there are bug incompatibilities between our application server and 1.6's XML handling which prevents part of our system working in 1.6.

So, most of the difficulties are really library related. But there's no way to use old versions of the standard libraries with new versions of Java / the JVM, so that doesn't make it any less of a problem.

On Compatibility

Java's compatibility is way better than most, I suspect. Yet, even if it were perfectly backward compatible with no thought required by anybody outside of Sun, it still probably wouldn't be ideal, because the future versions (apparently, as far as history to date indicates) must bend over backwards to stay backwards compatible. Witness the hack that is generics vs. other more gloriously sane approaches to that same issue. With every "improvement" you get not just the cognitive load of learning about that, but about why it is the way it is in light of history for the sake of backwards compatibility. That extra cruft is not ideal. Can we define or sketch out compatibilities, maybe even Ultimate Compatibility, and then see what tools exist or need to be invented to inch us in that direction? (I'm underpowered to actually contribute, so I'm more asking if folks know of work along those lines.) Or is there some simple proof that shows us what the limits are? And then can we still do something pragmatically useful within those constraints (e.g. type systems that are not guaranteed to terminate, or are O(n-squiared) can still be useful).

Regular releases.

Perhaps a good strategy for a language would be to put out regular releases every six months or every year (like Ubuntu). You could schedule one release every two years that could break reverse compatibility. The only other options are to either stagnate or pick some particular release to make changes (like Python 3000).

The only choice is stasis/stagnation

Are there no amazing practical or theoretical tools one could bring to bear on the compatibility problem? (As random food-for-thought: at the practical level, there have been folks proposing that people put a language version number in their source files. At a theoretical level, how about translators being part of the system so that when e.g. assert is ripped out from under you, you apply the standard translator to upgrade your sources?) It seems like the issues of versioning arise in many CS/SE related activities, is there study/development of relevant theory? I have seen some attempts, but haven't dug in enough yet to find others.

Language upgrade

Check out Python's __future__ mechanism. This is the proactive converse of deprecation: although limited it seems to be a pretty cool trick.

With Felix DSSL's you can provide a new grammar for every language version, without discarding old grammars. Of course this won't work if there is no way to map the old semantics onto a new system. This is roughly the same as upgrading a C library but providing a compatibility header file stuffed with ugly macros .. :)