Twitter github

Software Versioning is Ridiculous

Alright, I have to vent and go on a diatribe as its been awhile.

I was in the process of updating my iPhone and was greeted with these updates.

iPhone Update

1.34? 1.7f? Why does Apple even bother showing the version number. I don’t even know what version of the software was previously installed. As a user, I only really care if there’s an update and what is included in that update. That’s it.

The way software engineers treat version numbers is sad. Since the inception of software, we haven’t been able to come up with a reasonable versioning scheme that can be shared across technologies. Even worse, versions really mean nothing. On top of that, we confuse marketing version numbers with internal software version numbers. Here are some examples of what I’ve come across.

Let’s start with Java. 1.0.3, 1.1.2, 1.4.2, 1.5.0, 1.6.0? Why both with the “1” in the version number?

Next up we have is Windows… 3.1, 2000, XP, ME and 7. Awesome.

I remember when Netscape magically went from version 4 to 6. You know, we didn’t really need a version 5 because IE was already at version 6. We can’t let our competitors out version us.

In Linux… 2.3, 2.4.0, 2.6.8, 2.6.8.1… it’s cool when you can start adding version segments. Linux also seems to suffer the Java problem where the first digit is meaningless… maybe Linus’ favorite number is 2. On the bright side, the second segment in the version number at least signifies whether the code is considered stable or not. I’ll give bonus points to Linux for that.

SmallEiffel… -0.87, -0.79, -0.74… nice… software versions that start on the negative scale and apparently count down to zero.

In areas where modules exist and there’s a goal of reusable components (think OSGi and Maven), there’s a standard version scheme with a recommended policy on how to handle version changes. The only problem is that not everyone follows the scheme given their experience where version numbers mean nothing. It also doesn’t help that version schemes may be different amongst similar component technologies.

In the end, there really needs to be two types of versions, one for the marketing department and one for the development department. Confusing the two types is bad. It’s good to see that I’m not the only one that feels like this, there’s some funny commentary by Jeff Atwood on versioning.

Shame on us in the software industry for letting this crap continue.

  • I would say that Java version is consistent. You can still recompile a java 1.0.x program and have it run, same with the byte code. So they haven’t broken backwards compatibility, and the sun java library is famous for never removing deprecated components. If they did remove the deprecated classes and methods, then you have a non-backwards compatible change, and the major version would need to be updated.

    The Java 5, Java 6 is the marketing number. Java 1.5, Java 1.6 is the software number. I agree versioning sucks…and it needs to be standardized, not sure if we are ever going to live in that utopia though.

  • I would say that Java version is consistent. You can still recompile a java 1.0.x program and have it run, same with the byte code. So they haven’t broken backwards compatibility, and the sun java library is famous for never removing deprecated components. If they did remove the deprecated classes and methods, then you have a non-backwards compatible change, and the major version would need to be updated.

    The Java 5, Java 6 is the marketing number. Java 1.5, Java 1.6 is the software number. I agree versioning sucks…and it needs to be standardized, not sure if we are ever going to live in that utopia though.

  • Kelly Campbell

    Here’s a unique one: TeX uses extended digits of pi. http://en.wikipedia.org/wiki/Software_versioning#TeX

  • Kelly Campbell

    Here’s a unique one: TeX uses extended digits of pi. http://en.wikipedia.org/wiki/Software_versioning#TeX

  • @David Carver
    Actually, they broke backwards compatibility in 1.2.

    If you had

    import java.util.*;
    import java.awt.*;

    class Foo {
    List list = new List();
    }

    It would compile fine in 1.1.x, but in 1.2.x, kaboom! Ambiguous import.
    This is why Import On Demand Is Evil. (See http://javadude.com/articles/importondemandisevil.html)

    — Scott

  • @David Carver
    Actually, they broke backwards compatibility in 1.2.

    If you had

    import java.util.*;
    import java.awt.*;

    class Foo {
    List list = new List();
    }

    It would compile fine in 1.1.x, but in 1.2.x, kaboom! Ambiguous import.
    This is why Import On Demand Is Evil. (See http://javadude.com/articles/importondemandisevil.html)

    — Scott

  • Marketing vs. internal versions. I have had to fight so hard to get people to understand the difference. I can’t tell you how many times I’ve been forced to go back into code and change the version number that’s reported to match the marketing version. Sigh…

    The only time the user cares about the actual version number is when there is a new version in a box on a shelf and they want to know if it’s different from the one they have. Of course that could be served by “better” “better still” “even better” “more superbly betterified” and “betterriffic”, which we all know are in ascending order of betteritude. πŸ˜‰

  • Marketing vs. internal versions. I have had to fight so hard to get people to understand the difference. I can’t tell you how many times I’ve been forced to go back into code and change the version number that’s reported to match the marketing version. Sigh…

    The only time the user cares about the actual version number is when there is a new version in a box on a shelf and they want to know if it’s different from the one they have. Of course that could be served by “better” “better still” “even better” “more superbly betterified” and “betterriffic”, which we all know are in ascending order of betteritude. πŸ˜‰

  • Eugene Ostroukhov

    Even if they used some “marketing” version strings on this dashboard it would not help. I think it would me more then enough to have two version strings – “latest” and “old” πŸ™‚

    In most cases users do not care about exact version. Versions are more important to technical staff – IT, plug-in developers, etc. Technical staff really enjoys clean and easy-to-compare “technical” version string.

  • Eugene Ostroukhov

    Even if they used some “marketing” version strings on this dashboard it would not help. I think it would me more then enough to have two version strings – “latest” and “old” πŸ™‚

    In most cases users do not care about exact version. Versions are more important to technical staff – IT, plug-in developers, etc. Technical staff really enjoys clean and easy-to-compare “technical” version string.

  • Carey

    As far as I can tell, Linux version numbering has changed, and there will probably not be a version 2.7.anything. Two useless digits beats one for Java.

    (I remember running successive versions of Linux 1.2.x, compiled myself. I had to quit X to have enough memory for GCC.)

  • Carey

    As far as I can tell, Linux version numbering has changed, and there will probably not be a version 2.7.anything. Two useless digits beats one for Java.

    (I remember running successive versions of Linux 1.2.x, compiled myself. I had to quit X to have enough memory for GCC.)

  • Marketing is the major driver for a ‘public’ version number in most cases. You get some interesting stories – for example, at one point our (now ex-) marketing team decided that products with a major version “4” were bad luck. So we had products go from 3.1 straight to 5.0 (which basically allows you to break binary compatibility twice!). People who don’t care so much about that side of things have fun instead – like the Ο€ incident and negative range numbers. There’s also plain old intransigence like the silly Scala 2.7 vs 2.8 affair.

    @Scott – I’ve seen that happen sooo many times. I’ve always used version to tell a story – basically how hosed you are going to be once you upgrade. This ranges from 0) drop-in replacement; 1) we’ve changed some third-party stuff; 2) you’re going to have to re-write your scripts; 3) you’re going to have to re-link all your binaries, sorry; 4) you’re going to have to recompile everything, sorry; 5) you’re going to have to re-write your code, sorry, by the way we have a new training course.

  • Marketing is the major driver for a ‘public’ version number in most cases. You get some interesting stories – for example, at one point our (now ex-) marketing team decided that products with a major version “4” were bad luck. So we had products go from 3.1 straight to 5.0 (which basically allows you to break binary compatibility twice!). People who don’t care so much about that side of things have fun instead – like the Ο€ incident and negative range numbers. There’s also plain old intransigence like the silly Scala 2.7 vs 2.8 affair.

    @Scott – I’ve seen that happen sooo many times. I’ve always used version to tell a story – basically how hosed you are going to be once you upgrade. This ranges from 0) drop-in replacement; 1) we’ve changed some third-party stuff; 2) you’re going to have to re-write your scripts; 3) you’re going to have to re-link all your binaries, sorry; 4) you’re going to have to recompile everything, sorry; 5) you’re going to have to re-write your code, sorry, by the way we have a new training course.

  • @Eugene Ostroukhov
    I agree – latest/old would work great when you’re in an update manager. Won’t work so well on a box at the store though πŸ˜‰

  • @Eugene Ostroukhov
    I agree – latest/old would work great when you’re in an update manager. Won’t work so well on a box at the store though πŸ˜‰

  • @oisin

    5) you’re going to have to re-write your code, sorry, by the way we have a new training course.

    Hehehe… I bet that was a great driver for the marketing team to up the version numbers artificially…

  • @oisin

    5) you’re going to have to re-write your code, sorry, by the way we have a new training course.

    Hehehe… I bet that was a great driver for the marketing team to up the version numbers artificially…

  • Richard Steele

    While I agree that this does seem to cause problems, in my experience it’s as much a “techno-political” issue than anything else. Versions are arbitrary, as long as they can uniquely identify a specific release of the product. Don’t forget another important reason for version numbers: support. “What version are you running, and what version of the OS are you running it on?” are very often the first questions we need answered to address a support call.

  • Richard Steele

    While I agree that this does seem to cause problems, in my experience it’s as much a “techno-political” issue than anything else. Versions are arbitrary, as long as they can uniquely identify a specific release of the product. Don’t forget another important reason for version numbers: support. “What version are you running, and what version of the OS are you running it on?” are very often the first questions we need answered to address a support call.

  • @Richard Steele, I disagree with your assertion around version numbers being arbitrary especially when it comes to module systems.

    Richard Steele :
    …Versions are arbitrary, as long as they can uniquely identify a specific release of the product…

    Let me give you twos examples from OSGi land to think about. In OSGi, you can depend on different bundles using the Require-Bundle header. You can depend on ranges. Let’s say you were writing an application that needed to use log4j. What version of log4j do you want to depend on? The first stab of your dependency can be written like this…

    Require-Bundle: org.apache.log4j

    You go to deploy your bundle on one system. It works, yay!

    You know go to deploy your bundle on some other system or someone else deploys your bundle… you get some crazy exceptions. It turns out, you were developing against log4j 1.1 and that worked great when deployed into the first system that was running 1.1… however… the second system your bundle was deployed to was running 1.2 and in version 1.2… the log4j team decided to break binary compatibility. Ok, you can now fix your bundle with this dependency statement:

    Require-Bundle: org.apache.log4j;version=[1.1,1.2)

    Now imagine that you needed commons collections? How should you depend on commons collections… what version ranges… what verison policy does the commons collections team follow?

    Require-Bundle: org.apache.commons.collections;version=[2.1,3.0)

    It turns out that commons collection 3.0 is binary compatible with 2.1…

    You see what I’m getting it?

    When there is no consistent set of versioning semantics when it comes to module systems… it’s a world of pain.

  • @Richard Steele, I disagree with your assertion around version numbers being arbitrary especially when it comes to module systems.

    Richard Steele :

    …Versions are arbitrary, as long as they can uniquely identify a specific release of the product…

    Let me give you twos examples from OSGi land to think about. In OSGi, you can depend on different bundles using the Require-Bundle header. You can depend on ranges. Let’s say you were writing an application that needed to use log4j. What version of log4j do you want to depend on? The first stab of your dependency can be written like this…

    Require-Bundle: org.apache.log4j

    You go to deploy your bundle on one system. It works, yay!

    You know go to deploy your bundle on some other system or someone else deploys your bundle… you get some crazy exceptions. It turns out, you were developing against log4j 1.1 and that worked great when deployed into the first system that was running 1.1… however… the second system your bundle was deployed to was running 1.2 and in version 1.2… the log4j team decided to break binary compatibility. Ok, you can now fix your bundle with this dependency statement:

    Require-Bundle: org.apache.log4j;version=[1.1,1.2)

    Now imagine that you needed commons collections? How should you depend on commons collections… what version ranges… what verison policy does the commons collections team follow?

    Require-Bundle: org.apache.commons.collections;version=[2.1,3.0)

    It turns out that commons collection 3.0 is binary compatible with 2.1…

    You see what I’m getting it?

    When there is no consistent set of versioning semantics when it comes to module systems… it’s a world of pain.

  • themhz

    Ahahaha, your funny, I like your post. But one thing that is very important to know is that when you have a problem with your iPhone you call the company complaining that you have a problem with the gd phone and you need a fix now!. How the hell will the support figure out what is the “possible” problem when they don’t get the version number of the phone or the software? You have to understand that the number there is very important for you and for the company. Think that for software versions you add modules all the time untill you reach a version point. If a user has a software backdated because he not so in with technology or he is ok with his current functionality of V.1.0.0 and I made like v.1.5.3, and he doesnt tell me his version, how am I supposed to know if the problem is CAUSED BY SOMETHING I DID YESTERDAY OR SOMETHING I DID BEFORE ONE YEAR?

    Anyways. Peace and love..