
Peter Simons
Hi Clark.
I think we just use dependencies [to specify] different things.
If dependency version constraints are specified as a white-list -- i.e. we include only those few versions that have been actually verified and exclude everything else --, then we take the risk of excluding *too much*. There will be versions of the dependencies that would work just fine with our package, but the Cabal file prevents them from being used in the build.
The opposite approach is to specify constraints as a black-list. This means that we don't constrain our build inputs at all, unless we know for a fact that some specific versions cannot be used to build our package. In that case, we'll exclude exactly those versions, but nothing else. In this approach, we risk excluding *too little*. There will probably be versions of our dependencies that cannot be used to build our package, but the Cabal file doesn't exclude them from being used.
Now, the black-list approach has a significant advantage. In current versions of "cabal-install", it is possible for users to extend an incomplete black-list by adding appropriate "--constraint" flags on the command-line of the build. It is impossible, however, to extend an incomplete white-list that way.
In other words: build failures can be easily avoided if some package specifies constraints that are too loose. Build failures caused by version constraints that are too strict, however, can be fixed only by editing the Cabal file.
For this reason, dependency constraints in Cabal should rather be underspecified than overspecified.
The blacklisting approach has one major disadvantage that noone has mentioned yet: Adding more restrictive constraints does not work, the broken package will be on hackage forever, while adding a new version with relaxed constraints works well. Consider the following example: A 1.1.4.0 build-depends: B ==2.5.* C ==3.7.* (overspecified) B 2.5.3.0 build-depends: C ==3.* (underspecified) C 3.7.1.0 Everything works nice until C-3.8.0.0 appears with incompatible changes that break B, but not A. Now both A and B have to update their dependencies and we have now: A 1.1.5.0 build-depends: B ==2.5.* C >=3.7 && <3.9 B 2.5.4.0 build-depends: C >=3 && <3.8 C 3.8.0.0 And now the following combination is still valid: A 1.1.5.0 B 2.5.3.0 (old version) C 3.8.0.0 Bang! Tobi PS: This is my first post on this list. I'm not actively using haskell, but following this list for quite a while just out of interest.