A strong commitment to backwards compatibility means keeping your mistakes
11–20 of 62 posts
Re: A strong commitment to backwards compatibility means keeping your mistakes
#12I'd say nonsense. Backwards compatibility is better than any other option. From time to time you need to provide new, clean versions of old APIs and that's it. Things get deprecated (as in "best not to use this unless you are aware of the consequences". Aggregate over time, don't replace. Garbage collect when not reachable. This works for APIs as weel as for functional programming data structures. Clojure(script) app…
Re: A strong commitment to backwards compatibility means keeping your mistakes
#13Earlier quoted context omitted.
> if any complex enough system is long-term commercially viable I don't think you can determine this from first principles without taking the wider world into account. Things like the electricity grid or car manufacturing seem to have managed just fine over long periods of time, despite (almost) nobody having their own coal power plant or cylinder boring machinery. There are some niches in software that will survive…
>electricity grid or car manufacturing electricity grid became a commodity (I believe arguably car manufacturing did as well), not sure if the theory isn't that any system that lasts over the long term will either become commoditised or cease to be commercially viable.
Grid equipment itself is manufactured by unglamourous heavy engineering firms like Siemens or ABB.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#14You can't keep BROKEN functions "because people rely on them", but you can't suddenly make a minor release (e.g.: from 2.3.4 to 2.3.5) completely changing the semantic of a feature you expose.
You need to:
- Avoid changing APIs just for the sake of change.
- Announce breaking changes.
- Document how users are intended to migrate from your old API to the new one.
Very large projects like Django do things like:
- v2.0: Adds a new API, but keeps the old one
- v3.0: Removes the old API.
This gives consumers of the API plenty of time and margin to experiment with both and move on.
If a single release changes too many things, it's very hard for a developer to upgrade, since they have a completely broken codebase, and need to fix multiple breakage at once.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#15I'd say nonsense. Backwards compatibility is better than any other option. From time to time you need to provide new, clean versions of old APIs and that's it. Things get deprecated (as in "best not to use this unless you are aware of the consequences". Aggregate over time, don't replace. Garbage collect when not reachable. This works for APIs as weel as for functional programming data structures. Clojure(script) app…
Suppose you create an API that allows users to enter nonsensical data or do things that are very bad for performance. Later, you realize your mistake, create a new, improved version of your API, and deprecate the old API. However, as long as you keep the old API for backward compatibility, you will have to deal with nonsensical data and poor performance.
We've seen this with Python2->3 transition. If the new version isn't backwards compatible (requires non-trivial work to transition), what you've done isn't an upgrade: you've created a new product, and deprecated the old one. As we've seen from Google, people hate it when that happens (how many different eras of deprecated chat app are Google on now?)
Other examples: Windows has, on a couple of occasions, attempted architecture transitions. Windows RT was the latest. They've not yet made the leap to ARM, despite having cutdown versions of Windows (CE) running on ARM for something like 20 years. Apple have managed multiple architecture transitions by providing emulators, bridges, "fat binaries" that work across the transition, and a history of being willing to tell both developers and customers to get stuffed if they don't like it.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#16It's ok to keep backwards compatibility, but the API needs to also move forward and get the bugs ironed out. The worse case is when developers start to rely on the bugs for their workarounds (yes, please, do test your API before releasing)
Maybe shims are the way to go. Instead of keeping old functionality around you make a shim that only talks to the new API. And that will serve as a guide (because if you're taking functionality out that's usually not good). I've seen a couple of cases where the deprecated API was much more straight forward and easy to use than the new one. Not good.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#17The reality is that you have to be sensible and balanced. You can't keep BROKEN functions "because people rely on them", but you can't suddenly make a minor release (e.g.: from 2.3.4 to 2.3.5) completely changing the semantic of a feature you expose. You need to: - Avoid changing APIs just for the sake of change. - Announce breaking changes. - Document how users are intended to migrate from your old API to the new on…
It's not a silver bullet though, as we saw with the move to Python3. It annoyed people with large Python2 codebases, giving them the choice between:
• Laboriously reworking their code to transition it to Python3 (a language with only limited advantages over Python2)
• Using an unsupported language for a significant codebase
Re: A strong commitment to backwards compatibility means keeping your mistakes
#18I'd say nonsense. Backwards compatibility is better than any other option. From time to time you need to provide new, clean versions of old APIs and that's it. Things get deprecated (as in "best not to use this unless you are aware of the consequences". Aggregate over time, don't replace. Garbage collect when not reachable. This works for APIs as weel as for functional programming data structures. Clojure(script) app…
Suppose you create an API that allows users to enter nonsensical data or do things that are very bad for performance. Later, you realize your mistake, create a new, improved version of your API, and deprecate the old API. However, as long as you keep the old API for backward compatibility, you will have to deal with nonsensical data and poor performance.
We are talking about an API, not a shared service.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#19The reality is that you have to be sensible and balanced. You can't keep BROKEN functions "because people rely on them", but you can't suddenly make a minor release (e.g.: from 2.3.4 to 2.3.5) completely changing the semantic of a feature you expose. You need to: - Avoid changing APIs just for the sake of change. - Announce breaking changes. - Document how users are intended to migrate from your old API to the new on…
> This gives consumers of the API plenty of time and margin to experiment with both and move on. It's not a silver bullet though, as we saw with the move to Python3. It annoyed people with large Python2 codebases, giving them the choice between: • Laboriously reworking their code to transition it to Python3 (a language with only limited advantages over Python2) • Using an unsupported language for a significant codeba…
There was no intermediate release that could run both python2 and python3 code.
It introduced new features AND removed the old ones all at once.
Re: A strong commitment to backwards compatibility means keeping your mistakes
#20Yeah this pushes developers of the platform between a rock and a hard place. It's ok to keep backwards compatibility, but the API needs to also move forward and get the bugs ironed out. The worse case is when developers start to rely on the bugs for their workarounds (yes, please, do test your API before releasing) Maybe shims are the way to go. Instead of keeping old functionality around you make a shim that only ta…
If you have a much improved design which allows for a better implementation then it would be perfectly fine if you reimplement the old API on top of the new API. As long as this is strictly transparent (source and binary, if this makes sense), then why not.
Linus attitude about not breaking user space is the correct one.