State of the Cabal - Q1+Q2/2021

@kindaro some clarifications:

This was partially true for package databases, but environments are just a set of “pointers” to actual packages in the cabal store, so deleting and recreating them is very quick, and you don’t have to delete your cache.

There is some documentation about them at the ghc side: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html#package-environments

The install --lib docs explain the practical usage with current cabal: https://cabal.readthedocs.io/en/3.4/cabal-commands.html#cabal-v2-install

cabal env will of course have its own section

With cabal env, there will be a way to remove a package from an environment (the prototype linked in the issue can already do this)

Or, if you mean actually freeing up the space from the cache, there is #3333, but it’s lower priority

2 Likes

There is also a prototype garbage collector called cabal-store-gc in the cabal-extras-suite.

3 Likes

Right, but then the build is not very well-guaranteed to be reproducible.

This sort of “design philosophy” is unfriendly to users and the sort of thing that leads us to give up on the tool. If I can not sufficiently figure out how to use the tool, in a reasonable amount of time, the tool is a distraction and probably not worth the time invested.

Stack lets me be productive while I also continue to learn about haskell, the tools, how the packaging ecosystem works, etc. Cabal prevents me from learning until I have learned enough to use it in basic ways. That’s a really frustrating, but also avoidable.

4 Likes

Yes, but I only use it for one-shot purposes; to try out things quickly and then forget about them. So reproducibility is not a concern.

1 Like

xmonad scripting also needs to have dependencies in scope without a project

Indeed, xmonad invokes ghc to recompile itself and it expects the xmonad and (usually) xmonad-contrib libraries in scope. That has probably been broken since cabal switched to v2 by default. I’m not a cabal user myself, but I am told that cabal install --lib --package-env=$HOME/.xmonad/ works these days just as well as v1 install did. I shall try this somewhere and update our documentation before the next release.

Many of our users use stack and the same problem is there as well, without as nice a solution. We now tell users to create a custom build script that invokes stack exec ghc … from wherever their stack.yaml is. That’s silly and we should probably at least check for ~/.xmonad/stack.yaml and use that to make common setups easier.

To add to the rest of the debate, I’ll just note how I personally deal with what you folks use cabal install --lib for: I’ve been a user of stack for a while, and I usually commit to a single version of Stackage LTS that I use in both the global ~/.stack/global/stack.yaml as well as the stack.yaml that I use for xmonad and arbtt and ghcid and other tools. Therefore, whenever I stack ghci in my home or /tmp or wherever really, all the packages that have already been built from that LTS are available, and if not, stack build something is always happy to compile an additional package from the LTS snapshot and make it available globally.

Committing to a single old LTS version is obviously a rather conservative approach, but it usually works for me. Yeah, I happen to favor the “less deps, and if necessary, prefer boring deps” approach. :slight_smile:

1 Like

I’m not trying to put judgement on the practice, just focusing on the technical limitation. For example, if you were offering support to other haskellers, or otherwise posting the results to the web (where haskellers can read and learn from it), reproducibility is a valuable feature, and without it, the code decay is rather surprising.

2 Likes

While it’s been common in *nix for a while, to have an app like xmonad use a system-provided tool like ghc… there is an opinion on isolation and coupling that is growing on me: cat and mkdir, rm, etc are self-contained and have stable APIs, whereas the software used to build and run some other software is generally much more coupled, and in some cases highly sensitive to variances or details in versioning, configuration, etc, such that it actually makes a lot of sense to shove the coupled components together in isolation. In fact, this works so well we have built nix and nixos on the general idea. So while I understand how an app like xmonad has done what is has, it also seems to make sense to come up with solutions that give the app (xmonad/etc) a better and more efficient experience working with the coupled software, and in isolation from the rest of the system. This is partly why I shy away from tools and workflows that don’t provide the structures to make that type of efficient interaction and isolation the norm.

2 Likes

FYI xmonad works perfectly well with a custom cabal v2- build script, viz.

2 Likes

I used to do that, but cabal is quite slow to start even if nothing has to be recompiled, so now I use a makefile that uses cabal if files have changed. Oh, and you might want to add --overwrite-policy=always.

1 Like

I used to do that, but cabal is quite slow to start even if nothing has to be recompiled, so now I use a makefile that uses cabal if files have changed.

Yes, that’s true. I wish cabal would be quicker to determine that it needs to do nothing.

Oh, and you might want to add --overwrite-policy=always.

Ah, good idea, thanks! Perhaps I should even install to a temporary directory. That would be safer.

If you have a specific suggestion on what xmonad can do better, do not hesitate to tell us. We have an IRC channel, Matrix room, GitHub issues and a mailing list.

1 Like

Yes, I know it does. I just wish it wasn’t necessary.

It’s possible I’m focusing on the wrong problem though. If we did make frequent releases, people would just install the latest version from their Linux distro and they wouldn’t need to compile xmonad from git using cabal or stack, and they wouldn’t need to write custom build scripts. And maybe it’s completely fine that people who choose to compile from git are made to jump a couple extra hoops. Maybe it’s all right that xmonad becomes not just a Haskell gateway drug, but also cabal/stack gateway drug. :slight_smile:

Thanks for the welcome invite. I am not a user of xmonad and so don’t really have any suggestions. I was using the situation you presented as an example for the type of coupling and problems that creates for software dependent on the specifics of their build toolchains. I guess as an orthogonal point, also the complications we get when we install those toolchains from distros’ pkg repositories (apt/etc), as we typically need freedom to install multiple copies/versions of those toolchains in order to build software projects with different build requirements (nix makes this easier, as does stack, and I assume ghcup, pyenv, rustup, etc would as well).

I realize this is going to a bit of offtopic, but I have a similar need which I have solved with nix. I have a bash alias gwp which creates a nix shell with the required packages in scope.

gwp QuickCheck hedgehog
gwp () {
	pkgs="$@" 
	nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz -p "ghcid" -p "haskellPackages.ghcWithHoogle (pkgs: with pkgs; [$pkgs])" --run 'zsh'
}
3 Likes

I made cabal-auto-expose for automatically picking up new modules ( including Backpack modules and signatures ) and generating a .cabal file for you allowing a stack like dev workflow. It allows control over each stanza using only the expose Cabal API and is packaged as a library and a CLI tool so maybe something to scavenge there.

8 Likes

Nice! Thanks @deech. We’ll see if there’s anything we can lean on for the exact printer

2 Likes