FAR Versioning

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

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 pkg, function foo takes a number, and pops out a string; other functions exist in there, too.

Breaking Changes

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 foo in 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 bar, and 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 bar and 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, pkg2).

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).


  1. Spec-ulation Keynote - Rich Hickey
  2. Spec-ulation transcription
Incoming Links

Last modified: 202401040446