
On 10/12/2020 22.07, Jack Kelly via Haskell-Cafe wrote:
Both tools have deficiencies, but looking at the "10 year overnight success" that is the recent step-change in the quality of Haskell's Language Server Protocol support, I am hopeful for the future. The answer is not as simple as "just use stack" or "just use cabal-install". I do not want to kick off a build-tool flamewar, but neither cabal-install nor stack are magical Christmas lands where everything is perfect. Here are a collection of objections to/my frustrations with stack, which is why "just use stack" isn't an answer to the problem:
[--snip--] Absolutely agreed that there is currently to "Right Answer"(TM) wrt. Cabal or Stack. They do different things well/badly. Until we get a tool that can do everything the schism will probably remain. (And that's not even talking about issues like technical debt in each of the code bases, etc.) Anyway, just wanted to comment on a couple of points:
- hpack-by-default pushes another reinvention of basic haskell tooling, and does so with YAML, which is a file format that gets worse the more you understand it. (I expect its defenders will say this is just providing an option, but from my experience onboarding new Hackage uploaders, many people do not realise that hpack is optional.)
My problem here is that Cabal hasn't provided some very useful the features that YAML does out of the box, namely the ability to define arbitrary snippets of package configuration and to refer to them from multiple places. Examples: If I maintain a cohesive set of 5 packages, I need to duplicate various bits and bobs of information in 5 different places: - author info, license info - ghc options (I like to use identical options for all my packages in a 'set') - dependency version ranges(!) in 5 different cabal files. This is tedious at best and outright wrong at worst (inconsistent version bounds). YAML lets me avoid that annoyance -- yes, using entities and entity refs is a hackish way to do it, but it *works*. In no way am I advocating for YAML specifically. IMO, it's absurdly complex to cater for the needs of <1% of its users. However, I do wish Cabal could use some standardized format with similar capabilites for avoiding duplication in a full *generic* way. My problem with the cabal file format is that is basically entirely ad-hoc, esp. wrt. what I can avoid repeating over and over. (Dhall could work here since you can at least do inclusions and reuse in a generic way. Plus it has fully defined semantics plus implementations in at least a couple of langauges, Haskell and Scala.)
- Many stack projects do not provide bounds on dependencies, relying on getting exact versions from LTS. This may be defensible for applications that sit at the leaves of a dependency graph, but less so for libraries. Accurate bound information is one of the reasons LTS build plans can be easily constructed, and tooling that encourages sloppy bounds feels to me like it encourages taking without giving back to the shared resource (the common set of libraries on Hackage with well-understood bounds).
I posit that at least a *part* of the problem here is tedium for maintainers (see above), but while we're at it: I'm not sure manually maintaining bounds is at all scalable nor particularly "correct" (for lower bounds, esp.) unless one is *super*-vigilant about what bits of a dependency are *actually* in use. FWIW, I do try to do this for my packages, but I'm very confident that all of my packages probably have misleading lower bounds. It seems to me that some automated tooling is needed here, e.g. to try building/testing with e.g. all deps at the lower bound, all deps at the highest bound, etc. Regards,