views:

445

answers:

10

I hate capricious projects that change at the drop of a hat.

I hate projects which are overly complex trying to maintain backwards compatibility.

  • Where is the balance?
  • When maintaining a project, what should one take into account when deciding to break backwards compatibility or not?
  • How much effort should one put into conversion utilities and advance notice?

Followup:

A lot of great answers, thanks! Still, the balance question seems unattended. Some projects might stall because they can't add new features and maintain backwards compatibility, but they don't have the resources to provide a long upgrade cycle (ie, depreciate it for two releases, then make the change) or they may not be able to make utilities to convert.

Some answers intimate that there's an implicit promise between maintainer and user not to break backwards compatibility without providing a relatively easy upgrade path with a lot of notice.

  • Is it ever ok to break this promise, or should a project hold off on new features until it has the resources to provide an easy path?
+3  A: 

It depends on your users.

Some users need the backwards compatibility. And you need a lot of effort to convince them to upgrade. In that case you need to negotiate. Give them an painless upgrade tool. Maybe some features from their wishlist. But in the end you will always loose some of them.

Gamecat
+2  A: 

A couple comments/thoughts:

  • provide maintenance/support for only the current version and N prior versions. Publish this information widely.
  • Provide external tools for conversions/upgrades to keep it out of product
Tim
+7  A: 

At a minimum, you should keep features around, but marked deprecated for a release cycle or two. Gives you user base time to catch up with the changes, and an smooth migration path (because they can run the old and the new code at against the same installation of your tool).

Clear documentation of the changes, examples of how to migrate, tools to support data-conversion, an explicit schedule for how long they can rely on the old behavior, are all good to have, too.


Adam Davis asks in the comments about urgent situations:

Well, I would not recommend keeping gaping security holes around and enabled. But depending on who your users are, and what they are doing, you might still want to make them available. Adding a new switch, gives you a chance to warn them exactly what they are getting into.

dmckee
What about situations of urgency? You might not have the luxury of a few release cycles...
Adam Davis
"Adding a new switch, gives you a chance to warn them exactly what they are getting into." Ah, but then you get into the additional complexity of supporting backwards compatibility, so you really aren't breaking it, you're still merely depreciating it.
Adam Davis
::shrug:: It is all about providing as smooth and painless migration path as possible. An abrupt break **will** hurt your users. They **will** resent it. You pays your money and you takes your chances.
dmckee
+4  A: 

Even though we developers are usually technical oriented poeple, the balance in this case should be in your accounting: How much does it pay, how much does it cost?

If it costs you nothing (or very little), I would always recommend to maintain backwards compatibility. If it becomes more difficult, you need to estimate how much more you would have to spend on it (mostly working hours) and compare that with an estimation of how many customers you would loose or gain by not providing/providing compatibility with older versions.

Usually the new users do not care for older versions of your software, so in most cases the number here would be 0. It comes down to your existing user base, how likely they are to switch to a competing product.

I would recommend two things:

  1. Take a small survey of your users (or e representative sample) and see how important backwards compatibility is for them
  2. If you want to phase out a specific functionality, do it in two stages: in the next version replace it with the new functionality, but keep the old one for compatibility. In the second next version, drop the old functionality completely. That way the vast majority of your users will have gotten used to the new way and not even look for the old functionality.

Regarding your followup:

I wouldn't say there is an implicit promise. I would call it an implicit expectation by the user. You need to be aware that most users will have this expectation. I think that its ok not to meet that expectation, if it would carry too much problems for you.

The problem with your original question is that the decision needs to be made on a case by case base. It depends a lot on your users and the relationship you have with them. Those are non technical factors, so a technical answer is not possible IMO.

Treb
+7  A: 

My opinions (perhaps a little controversial)

  • If you break backwards compatibility, you have to provide conversion/migration utilities that work and are easy to use. Otherwise you're betraying your clients.
  • Given that the conversion utilities are provided, breaking backwards compatibility is no problem. Do it, when living with old decisions gets annoying to you.

The project should always hold off on new features until it has the resources to provide an easy migration path. Less features are better than broken compatibility.

Joonas Pulakka
Controversial? Sounds more like common sense to me. +1
Treb
If you cannot provide the utilities (resource constraints, perhaps) then do you drop the feature entirely? What if your customers also want the feature? At what point can you break that 'promise'?
Adam Davis
Hum, good question. I think you don't usually drop features in new software releases, you add and improve them instead (which involves change, and therefore conversion utilities may be needed). But what if you really want to drop a feature entirely, and not provide anything to replace it? Dunno...
Joonas Pulakka
No, sorry I wasn't clear. You have a new feature you want to add, but that feature breaks backwards compatibility and you can't provide a utility. Do you decide to add the feature and break compatibility, or do you not add the new feature?
Adam Davis
To your followup: I think that project should always hold off on new features until it has the resources to provide an easy migration path. Less features are better than broken compatibility.
Joonas Pulakka
+1  A: 

Breaking changes are painful in the short term, since customers must monitor your changes and implement changes in their own code and practices. Backwards compatibility is painful in the long term, because your ability to implement new features will grind slowly to a halt.

Each way has its advantages and disadvantages.

Justice
+1  A: 

It's a simple customer demand. Do you have customers that absolutely require backward compatibility? How much do you make from each customer? How much is backward compatibility costing you? When you're down to so few customers creating revenue and so much cost in maintenance, it's time to fire the customers.

Conversion utilities depend entirely on the customers that require conversion. Work it out like this.

+---------------------+--------------+
| Old Bad Code        | (some cost)  |
+---------------------+--------------+
| Replace Old Bad Code| (some cost)  |
+---------------------+--------------+
| Make Conversion Tool| (some cost)  |
+---------------------+--------------+
| Savings from better |              |
| code                | revenue      |
+=====================+==============+
| Bottom Line         | return       |
+---------------------+--------------+


Edit.

Backward compatibility of changes is not an implicit promise. It's a specific marketing strategy. Some folks think it's important. But it's not implicit -- either you promised it or you didn't. If you didn't promise backward compatible, then... you didn't promise backward compatible.

If the feature you are going to break is central or popular or important in some way, you have to fork your project into two incompatible versions. If you're breaking something central, it says the old design was not appropriate for the new use cases and you're starting again.

if the feature you are going to break is peripheral, hardly used or unimportant, just increase the major version number and move on. That's what major version numbers are for -- compatibility.

The only users who might care are those for whom your soon-to-be-broken feature is somehow absolutely central. So, the feature is not important to your product, but central to them. This conflict means they shouldn't have been using your product in the first place.

Preserving backward compatibility for folks who are failing to use your product as you intended isn't an implicit promise.

S.Lott
How do you adequately identify the users and their usage so you can gauge this?
Adam Davis
@Adam Davis: I don't understand the question. If they're paying customers you know who they are. If it's open source, you check with the community that posts changes and asks for support. Could you clarify your question, please.
S.Lott
A lot of open source software is used by people who aren't on the mailing list, only went to your website once to get the software, and maybe later to get the newer software, and don't need support. You don't know who they are or what they use.
Adam Davis
If you break compatibility of a feature, you might find out you've affected 45% of your silent users, and you won't find out until after you've made the change. You ask, "Do you have customers that..." - so how do you find out whether you have such users under these conditions?
Adam Davis
@Adam Davis: To find silent users: 1) deprecate noisily so they get warnings for the soon-to-be remove features and 2) fork the project so that the old stuff is left alone until the end of time.
S.Lott
+2  A: 

You should be concerned about backwards compatibility when

  1. It locks existing customers out of old data
  2. It requires existing customers to retrain to use the new software.
  3. Evaluate the impact of lack of backwards compatibility on your ability to support both old and new customers.

In short there is no simple answer other than like anything with your software development process you to evaluate changes in light of it's impact.

RS Conley
4. It hinders the ability to make a gradual changeover. A cautious customer will want to run new and old in parallel for a while. Having version N+2 being incompatible with version N is one thing; if N+1 is incompatible with either, that's bad.
David Thornley
+3  A: 

Break backwards compatibility whenever the project gets too messy, and time or money are wasted.

Prepare well and plan a long phase of transition. There are good examples from the industry where it is or was planned well:

  • In Python, version 3.0 breaks backwards compatibility. But the current version 2.6 already integrates Python 3.0 features to ease the transition, while keeping old features. People are expected to start using the new features so they can easily move to version 3.0 once 2.6 will not be supported anymore.

  • Apple's Intel machines broke backwards compatibility in that they wouldn't run the old binaries written for PowerPC machines. Before the transition, Apple worked hard behind the scenes, writing converters and rewriting their software so that people could run their software when the Intel machines came out.

wrong on PPC/x86: there's an emulator in place to run PPC binaries, so there's no broke compatibility. what happened was lack of a progressive solution for apps, so Photoshop couldn't just add some patches to make it 'half-native' like they did on the 68k/PPC transition.
Javier
What Intel Macs dropped was the support for the Classic environment, which was a transition from OS9 and earlier to OSX (another was Carbon, which would work in both environments). In other words, they dropped compatibility they'd had several years ago.
David Thornley
+1 Python's break with compatibility. It's a bunch of internals and a few very visible things (like the poor, abused print statement)
S.Lott
An important part of the Python transition is the `2to3` program for converting old scripts.
dan04
+1  A: 

I doubt there is one single answer, except possibly in the form of a long equation. What will break? How much of it? Is the conversion easy? Is backwards compatibility easy? What will you gain with the new version? Are you fixing an exploit, adding or removing a feature, tweaking for consistency? How will your community react? Who is your community? Will this need to happen eventually?

There are a lot of variables. If you think there's a simple answer, look at the controversy around the IE8 rendering engine and the solutions they tried.

James Socol