[Haskell-cafe] Re: [Haskell] Re: Trying to install binary-0.4

Daniel McAllansmith dm.maillists at gmail.com
Tue Oct 16 18:57:05 EDT 2007


Following is a summary of my thoughts on the matter, in large part so I can 
figure out what I'm thinking... apologies if it's a bit of a ramble.  All 
comments welcome.


Basically
 - version numbering which differs from Simon's proposal
 - precise dependencies, I think the same as Simon is proposing
 - 'permanent' availability of compatible package versions
 - never a need to update working cabal files
 - a cabal file installs exactly one version of a package


1)
Package version numbers are of the form x.y.z


2)
There are version-segment ordering functions cmpX, cmpY, and cmpZ.

cmpX and cmpY are globally defined and operate over non-negative integers.  
Perhaps cmpZ is globally defined, or could be defined per package, or be 
lexicographic, or... something else.  cmpZ could even be a partial ordering I 
suppose.


3)
A cabal file specifies how to build a single version of a package.
name: foo
version: 2.12.5

This cabal file will build version 2.12.5 of package foo.


4)
The dependencies in a cabal file define baseline versions of required 
packages.
depends: bar [3.4]
         baz [1.2.6, 3]

Version 2.12.5 of foo requires a version of bar that is API-compatible with 
3.4.0 and a version of baz that is API-compatible with 1.2.6 _or_ 
API-compatible with 3.0.0.
Note that this doesn't imply that baz 3.0.0 is API-compatible with baz 1.2.6 
(by definition it is not), it implies that foo is using a subset of the 
intersection of those two baz APIs.
Note that baz 2.y.z would not satisfy the dependency.  Perhaps a function was 
removed with the bump to 2 and restored only with the bump to 3.


5)
Package version numbers encode whether one version of a package is 
API-compatible with another version of the package.

Given two versions x.y.z and i.j.k of a package:

 - x == i && y == j
    ==> x.y.z is API-identical (hence API-compatible) with i.j.k, cmpZ can be 
used to determine preferred version

 - x == i && y > j
    ==> x.y.z is API-compatible with i.j.k, it has undergone 
compatibility-preserving changes, x.y.z is preferred to i.j.k

 - x > i
    ==> x.y.z is not API-compatible with i.j.k, it has undergone 
non-compatibility-preserving changes

 - otherwise
    ==> x.y.z is not API-compatible with i.j.k, it is a lower version that has 
less functionality


6)
A compatibility-preserving change is generally a change which just adds to the 
API.  Ross Paterson points out adding extra data constructors or instances 
may not be compatibility-preserving.

A non-compatibility-preserving change is generally a change which includes the 
removal of some part of the API.  It might also include changes which leave 
the API unmodified but significantly degrade usability, e.g. worse time or 
space performance.


7)
Once a version of a package is building successfully it remains available for 
a 'long time'.  If sufficient versions of a package remain available then 
API-compatible versions of required packages are always available, so the 
building of packages should never break.  An uploaded cabal file should never 
need to be changed, regardless of what happens to the packages it depends 
upon.


8)
If a version of a package is discovered to have security flaws or serious bugs 
it should remain available in a quarantined state until a fixed 
API-compatible version is available.


9)
Something (hackage?) could enforce adherence to version numbering policy.  At 
the least any new version uploaded that claims to be API-compatible can be 
test compiled against packages which depend on it.

Something (hackage?) could assist package maintainers in releasing a new 
version of their package with updated dependency information.  Hackage could 
attempt to compile against non API-compatible versions and report the 
outcome, for example foo 2.12.5 compiles with the new baz 3.0.0 but not the 
latest baz 2.y.z


Dan


More information about the Haskell-Cafe mailing list