Lies, Damn Lies and Upper Bounds in Haskell PVP

2013-10-16

I've got a few observation regarding the recent discussion on upper bounds in Haskell package dependencies:

I get the point of Joachim: it's easier to maintain a legacy system if all the versions are pinned. The more stable, the better. I get the points of Roman: it unnecesarily hurts composability of packages, there is more about a successful build than just version numbers.

Both authors seem to implicitly agree that the purpose of the upper bounds is allow a successful build at some point in the future. I think that upper bounds don't deliver on it.

  • an upper bound is almost always a conjecture, and usually a false one.
  • it doesn't guarantee a successful build.

What happens if a package is built against the latest version of the some library? The developer takes the major version of the dependency, and sets the upper bound to the next major version (exclusive). He doesn't know if the next major release will contain breaking changes, nor if the next minor release will be compatible. We can't predict the future (unless we control it). I did see breaking changes in minor releases on Hackage. I see major releases which keep the API relatively stable.

The only information an upper bound contains, is what was the major version of the dependency at the moment of the release. It doesn't imply compatibility within the entire version range. It doesn't imply incompatibility beyond the required version range. It doesn't give the exact version numbers which are known to produce a successful and correct build.

I think that upper bounds should not be used unless

  • the package depends on the older version of some library, and it is incompatible with the latest version (see also this proposal);
  • or the developer knows that the next version of the library is going to introduce breaking changes (like if he maintains or follows the development of the library).

Instead of guessing upper bounds we need to publish known good build configurations (both tools' and dependencies' versions). That would be much more helpful to reproduce a build in the future. And this is the kind of information that is easy to verify before publishing, that is likely to stay true forever. Whether it should be the package maintainer, cabal, or hackage to take care of publishing build configurations, is another question.