There are a big number of programming languages. Some of them grow up and become very popular. People use such languages more and more often. The founder of such language (or founding organisation/community) may try to implement changes to make the language better. But sometimes it's hard to make some changes because of backward compatibility and such ugly things have already existed in the language for years, and are used by many users.

Are there any architectural principles or steps, during the language design phase, which can help to make it more stable so the language designers won't be as afraid to break backward compatibility?

  • 2
    language stability exclude making any kind of breaking changes. Can you clarify your question? Commented Nov 10, 2014 at 19:35
  • More stable means to me fewer changes happening (hopefully because they aren't necessary), the exact opposite of backwards-incompatible changes. Which are you interested in, or are you asking about both semi-independently?
    – user7043
    Commented Nov 10, 2014 at 19:35
  • @Simon how to design a language that when you are trying to add new feature you are not afraid to brake back comparability Commented Nov 10, 2014 at 19:41
  • @delnan lets say, both. Commented Nov 10, 2014 at 19:42
  • @viakondratiuk Not being afraid is not something language design can change. A better question might be "How to design a language so that adding new features doesn't cause breaking changes?".
    – svick
    Commented Nov 10, 2014 at 23:14

3 Answers 3


Language stability is not a technical decision. It is a contract between the language author and the users.

The author advertise a given version as more or less stable. The less stable a language is, the more changes the author can make. Each user interested by the language can decide if he wants to invest time in it to learn new features or develop applications that might be broken by next month's update.

Using an unstable language can be interesting because you are interested by a new concept, or you want to help by giving your feedback. If you are a business, you might prefer to wait for a technology to be more stable before investing your time in it.You care more about stuff like time to market, and user experience.

So this is a communication & trust issue. Look at the rust language development. They are crystal clear about what they are changing and what they are keeping. When they want to delay a decision about a given feature, they use what they call a feature gate. On the other side, the angular team faced a lot of anger over their 2.0 announcement because the changes were larger than expected.

Even libraries author have to communicate about the stability of their apis. Pretty much any technology used by other people have to strike a balance between stability and perfection. A car maker cannot change the position of the pedals, and a laptop designer won't invent a new keyboard layout for the same reason: you are not helping your users if you cannot make a decision about the way they will use your product.

  • Be aware that languages change throughout their life, regardless of how well it might be designed up front. Instead of trying to immediately ship the most awesome language on earth, first try to be useful and extensible. A mediocre langauge which I can actually use is worth more than any wonderful programming language that only exists in theory.
  • Consider facilities to make the syntax extensible, e.g. macros. Macros are not automatically a good thing and can be too powerful. Some languages have a very flexible syntax from the start which reduces the need for macros. A couple of scenarios to consider:

    • Can I introduce a new operator such as |> without leaving the language? Can I choose precedence and associativity for this operator?
    • How much ceremony do I have to go through for an inline function/lambda/closure?
    • Can I use existing language syntax to implement a foreach loop syntax? E.g. Ruby and Scala can do this through their flexible method call syntax with lambdas.
  • Consider facilities to keep semantics extensible. Common needs are:

    • Operator overloading, where user-defined types can assign their own meaning to existing operators. This makes a language much more enjoyable in maths-heavy applications.
    • Literal overloading. Can I make string literals be of my own string type? Can I make all numeric literals in the current scope be bignums?
    • Metaobject protocols. If the language doesn't have traits, can I implement them inside the current object system? Can I implement a different method resolution order? Can I swap out the way objects are stored or how methods are dispatched?
  • Have regression tests. Lots of test. Not only written by the language designers, but also by users. When adding a feature breaks these tests, carefully weigh the benefits of that feature against the benefit of backwards compatibility.
  • Version your language. Not just in your documentation, but also in the source code itself. Once you do that, the only part of your language that cannot change is this version pragma syntax. Examples: Racket allows you to specify a dialect. Perl allows you to use v5.20, which enables all backwards-incompatible features of Perl v5.20. You can also load single features explicitly like use feature 'state'. Similar: Python's from __future__ import division.
  • Consider designing your language in a way that results in few reserved words. Just because class introduces a class does not imply that I wouldn't be able to have a local variable named class. In practice, this results in keywords that introduce variable or method declarations, counter to the C-like tradition of using type names to introduce declarations. Another alternative is to use sigils for your $variables, as in Perl and PHP.

Parts of this answer are influenced by Guy Steele's speech “Growing a Language” (1998) (pdf) (youtube).

  • Some of your points talk about programmers using the language being able to extend it and some of them talk about designers of the language being able to extend it. Aren't the two mostly unrelated? And I think the question is talking about the latter kind.
    – svick
    Commented Nov 10, 2014 at 23:21
  • @svick The idea is that a language is so extensible by end users that much extension and experimentation can be done without changing the language itself. Metaobject protocols, operator overloading, and macro systems are a way to leave the door open for later changes. Anything that is implemented through these doors does not fundamentally break the language. Unfortunately, these doors themselves might have to be redesigned later. That's where the premise of Simon's answer kicks in: before you promise stability, do a bit of beta testing to find out whether your language actually works.
    – amon
    Commented Nov 11, 2014 at 8:13

I think a pretty important step is to promote a package manager whicih can also manage the version of the language itself.

For instance, I use SBT for Scala or Leiningen for Clojure. Both of them let me declare which version of the language I want to use, per project. So it is quite easy to start green projects in the latest version of the language, while upgrading the existing projects at a more comfortable pace, if ever.

Of course, depending on the language, this may still leave you with the need to wait for the relevant libraries to be ported to the version you need (this happens, for instance, in Scala), but makes things easier nevertheless.

  • with the corollary that as much of the language as possible should be defined in importable packages/modules as possible
    – jk.
    Commented Nov 11, 2014 at 10:37
  • Yes, but not necessarily. For instance, the compiler of Scala happens to be written in Scala, but when you set the Scala version in sbt, it is just fetched as a Jar and used to compile your sources. Even if it was an opaque binary, that would do as well. Now, there are reasons to define as much of the language as possible should be defined in importable packages, but those are covered in amon's answer
    – Andrea
    Commented Nov 11, 2014 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.