FAR is a type of versioning proposed by Rich Hickey.
What FAR Is
FAR is an acronym containing what you should do when growing your software. It stands for
- Fixation - Fixing bugs
- Accretion - Adding new features
- Relaxation - Requiring less from your users
Essentially, when a contract is created with the user, these are the appropriate operations that can be done when versioning that package. For instance, in package
foo takes a number, and pops out a string; other functions exist in there, too.
The biggest difference between this and semantic versioning is what happens when a breaking change is proposed.
In semantic versioning, this would be a "major" bump. But what happens with this is the features that are being used are changed while people are using them, and then they have to rewrite their program to try and accommodate these changes. Function
pkg will now require different arguments, or spit out different data, maybe. If a user wants to continue using the same
foo, they have to remain using stale, possibly insecure, functions
baz. To get the new features of
foo, they have to overhaul, refactor, and migrate everything in
pkg. I have seen this in every place I've worked, where migration is essentially never an option.
In FAR, you should never have a breaking change. You leave the original function and create another that serves the same purpose but more to what you are looking to improve. Then your users can have function
foo in library
pkg, which will always take in the same stuff, and return the same things. And new function
foo2 (or whatever better name you have) does what
foo did but much better. So your users can use the older version of
foo but not be fucked for the new versions of functions
baz. And migrating to
foo2 isn't a devastating life-altering event.
In short, always opt for accretion, and never remove. Removal is breakage, plain and simple, and is fucking over your customer. If you must remove something or change something so drastically that the user contract can no longer be fulfilled, it must be created or done under a different name (e.g.
foo2 instead of
foo, or worse,
But what are the versions?
This is the open ended part of this puzzle. But interestingly, this is no longer such a big deal if this process is followed well. Since contracts are no longer variable, you can always assume that using
pkg/foo will give the same result. So one proposal Rich had was something like
YYYYMMDD.HHMMSS, since that gives some kind of actual semantics to the user (the age of the package).
- Spec-ulation Keynote - Rich Hickey
- Spec-ulation transcription
Last modified: 202311150507