How do programming languages maintain backwards-compatibility AND fix design mistakes?

1.5k views Asked by At

As you know if you've read some of my other questions, I'm writing a programming language. One of my big concerns is that many languages have troubles with backwards compatibility, and I wish to avoid such issues. On one hand, I've seen a lot of pain and agony in the Python community over the switch to Python 3000 because it breaks backwards compatibility. On the other hand, I've seen C++, which started off shackled to C syntax and has never really recovered; i.e. the syntax of C is a poor fit for many C++ constructs.

My solution is to allow programmers to add a compiler directive to the file which will tell the compiler which version of the language to use when compiling. But my question is, how do other languages handle this problem? Are there any other solutions that have been tried, and how successful were those solutions?

6

There are 6 answers

1
Norman Ramsey On BEST ANSWER

When something is broken, the courageous language designer must not be afraid to break backward compatibility. I know of two good ways to do it:

  • The Glasgow Haskell Compiler typically deprecates unwanted features and then drops support after two versions.

  • The Lua team have a policy that each major release (there have been 5 since 1993) may break backward compatibility, but they typically provide a compatibility layer that helps users migrate to the latest version. (Plus they are scrupulous about keeping everything available; the current version is 5.1 but I have Lua 2.5 code that I still maintain, and if I find a bug in Lua 2.5, they will fix it.)

2
Breton On

I forgot one other way that languages have dealt with backward compatibility: Stubbornly insist on never updating the language. See Donald Knuth's TEX for an example of this.

8
Freddy On

Easy : Deprecation

When new methods or functions are available, they don't simply eliminate the old ones. They just deprecated them. So, developers working on new compilers know that at some point they will need to use the new versions of those functions or in the future their program won't compile. In that way they are 'backward compatible' but at the same time enforcing the usage of the new functionality.

2
Jim Ferrans On

I think you're on the right track with a compiler directive. It's may be better to package that as a command-line argument to your compiler though.

No matter what, in your compiler logic you can test against the version something like this:

if ( language_major_version > 2 )   // 2.00.00 and above
    ... normal processing ...
else
    ... emit compatibility/deprecation error ...

VoiceXML, an XML-based language for specifying voice dialogs, is one example of putting the directive in the source code:

<?xml version="1.0"?>
<vxml version="2.1">
    ...
</vxml>

Since the syntax is always well-formed XML, this is really easy to implement, almost cheating,

0
Breton On

I'm going to be the really harsh sobering voice and say: You're never going to have enough users for it to matter. Sorry, but the statistics are against you.

In the unlikely event that it does become a problem, these are the strategies I've seen used for this problem

  • Don't worry about it and just break backward compatibility

  • Keep old versions of the interpreter packaged in with the new versions and switch using some directive, or other kind of metadata

  • Make new versions a strict superset of old versions. That way, all old programs compile in the new version of the compiler/interpreter

  • Provide a converter to convert old style programs to new style programs.

  • Base the language on a virtual machine that accepts bytecode compiled from any version of the language. Ensure that there are facilities for different versions to "talk" to eachother.

  • Compromise and end up pissing everyone off instead of just half of your audience

  • New versions have a loose mode by default and a "strict" mode, the former being strictly backwards compatible, the latter removing old and busted features for those who opt in.

The good news is that none of these strategies work extremely well, so you have the opportunity to be creative and mess up in a novel new way.

0
Andrew Siemer On

Generally speaking you continue to support all the old features for at least one new version though preferably two versions into the future. Then the feature is depreciated and it is up to the user of your language to update their applications prior to the feature being dropped from your language.