I’ve spent unbelievably crazy amount of time in dozens of my open-source Haskell projects on supporting both cabal
and stack
, maintaining proper lower and upper bounds, compiling with multiple GHC’s (and maybe even multiple Stack snapshots), and fixing various bounds-related errors.
It was huge busy-work and led to massive burnout, so my current view is
I would prefer to do as less as possible such busy-work
Remember, that almost all Haskell developers are volunteers who spend their free time on this kind of work. As much as I’d like others to maintain their bounds properly and care more about backwards compatibility, I can empathise with not having the desire to do more non-interesting work for free. I can’t ask others to do more so I can do less. It doesn’t work that way.
As a consequence, I’m not convinced that any solution that requires volunteers to do more (e.g. using an extra tool like like cabal-plan-bounds
and building a potentially big project with multiple GHC versions locally to edit dependencies instead of just editing dependencies) will ever work on massive scale.
Asking people to perform extra steps only works for people who care deeply about some issue so they’re eager to invest more time or for people willing to pay money for doing this kind of work.
You may argue that cabal-plan-bounds
actually reduces the amount of work due to the following claim in README, “You never have to edit the build depends manually again”, but in my view, it just replaces one kind of busy-work (editing bounds manually) with another (building project locally multiple times).
IMO, the status quo is unfortunate but not critical. I see several problems with bounds of packages in Haskell at the moment but w.r.t. to problems discussed in this thread:
-
Incorrect lower bound: a package specifies bounds
>= x.y && < a.b
but doesn’t actually build with x.y
(e.g. due to using features appeared only later and not testing x.y
version)
- As a consumer of this package, I can mitigate the problem by specifying a greater lower bound in my own config.
-
Incorrect upper bound: a package specifies bounds
>= x.y && < a.b
but doesn’t actually build with a.(b - 1)
(e.g. due to build tool not choosing this version when building the package)
- Similarly than before, I can adjust bounds when consuming.
- Although, if I’m doing this in my package and I really want to check that the new version is properly supported, I need to edit the
.cabal
file to allow only the latest version, build, patch and relax constraints again.
mtl
maintainers are the same volunteers as everyone else. If they claimed that mtl
can be built with trasformers == 0.6.*
but haven’t actually tested this, nobody can blame them. Testing multiple build plans can lead to combinatorial explosion.
The main problem here is that transformers
is a boot library that had some backwards incompatible changes, and mtl
can’t just upgrade lower bound to use only the latest version of transformers
. Fixing that would go a long way but it’s not an easy issue to fix, I agree
Facing all of the above could be annoying, especially when reading confusing build plan errors, but if we want to address this problem and make a noticeable impact, it makes sense to identify all bounds-related problems and think about the most user-friendly way to resolve them.