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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe