"Is cabal-install stable enough yet that GHC should be inflicting it on newbies?"

Ok … (This was covered in the thread we split from.) The only appearance of “install” on that page:

  • GHC is a breeze to install using [ghcup] or [Stack]

either of which leads to cabal-install. (I agree it needs quite a bit of digging to find that out.)

If you bravely (for a newbie) take one of the [download] links at the top of that page:

… For most users, we recommend installing a [proper Haskell distribution] instead of GHC alone. …

And that page is much more explicit about cabal-install.

You’d have to be pretty pigheaded (like me) to scroll down to the ‘Distribution packages’ and download a .tar. (But that was the only way to go about it when I started with GHC; and indeed it’s the most common way to get going with most software I tinker with; and I want to run my virus-checker over anything before it touches my machine; and I don’t trust all those commands I see on the other approaches, especially when I see Bypass ... SecurityProtocol.)

For you there is this link to instructions for manual installation: I don’t like curl | sh. It’s in a small font below the automatic installation command.

2 Likes

Personally, I don’t think those links lead to anything that is unduly Cabal (the tool)-centric. I consider the GHCup project and Haskell.org’s downloads page put Cabal (the tool) and Stack on broadly equal footing.

However, I do think that the close association of Cabal (the tool) with Cabal (the package description specification) and Cabal (the library) is a double-edged sword, in that somebody new to Haskell landing at the Cabal User Guide encounters a large document which, although structured and indexed, covers a wide territory.

Stack’s own online documentation struggles with what I call the Swiss Army knife problem - “How do you tuck away all the other tools, when a user starting out just wants the main knife?” - but it has the advantage that it is just documenting one program.

2 Likes

Thank you for that feedback. So my line of thought is wrt the stage of “just need GHC”.

So … ? All the Google hits that say Stack is just a different front-end to cabal-install are wrong?

You’re expecting a newbie to be able to make a choice between different tools? I was expecting the employer or the instructor would make that choice for them. And I’m asking why that choice would necessitate 'project’s when I think all I want is programs. I’m entirely happy with multi-module programs: put all the .hs sources in the same directory; import them to Main, same as import from Base Libs (which are in a different directory, but it just works, I don’t need to worry my pretty head).

You’re just not persuading me that – at the stage of “just need GHC” – any tool, or 'project’s rather than programs will help my learning experience.

Speaking for myself (not trying to imagine how it is for a newbie): Cabal or Stack seem to be complex programs with many ways to configure and use them. I just unzipped GHC out of the box. I’m aware GHC has many options; I hardly never set any of those; I’m not seeing why I’d want to layer another option-riddled tool over the top. None of my user experience with GHC(i) has been as pleasant as with (Win)Hugs.

If somebody says Stack and Cabal (the tool) are ‘just’ different ‘front ends’, then ‘just’ and ‘front ends’ are doing a lot of heavy lifting. To explain:

  • both Stack and Cabal (the tool) are built on top of Cabal (the library) but even then their approaches to Cabal (the library) are quite different. Stack follows the original Cabal specification and accesses Cabal (the library) via a ‘setup’ executable. By default (it can be overridden by using a ‘Custom’ build type), for each specified version of GHC, Stack uses the version of Cabal (the library) that ships with GHC as a boot package. Cabal (the tool), as I understand it, uses only the version of Cabal (the library) that is specified as a dependency when the tool is built and is not making use of it only via the ‘setup’ interface. That is why, when a version of GHC is released, it specifies the versions of Cabal (the tool) that it will work with. Stack does not need to be updated for the same reason (but may need to be updated for other reasons: GHC’s undocumented hi file format is not guaranteed to be stable and Stack sometimes parses hi files).
  • Stack is also built on top of other technologies that Cabal (the tool), as I understand it, does not use. Examples are Casa (Content-Addressable Storage Archive) and Hpack (which is optional, recognisting that it has both fans and detractors). Cabal (the tool) can be used with Hpack, but only as stand alone tools.
  • Stack does things that Cabal (the tool) cannot do in isolation (including for convenience) and vice versa. For example, stack dot is a convenient way to understand dependency relationships; Cabal (the tool) does not have an equivalent. Cabal (the tool) tries to find package versions that work well together by assuming their dependency bounds are reliable; Stack only uses ‘curated sets of packages’ to address the same problem. ‘Only’ is seen by some as a Stack limitation, but that focus of approach also brings some benefits.
  • Finally, I would not use ‘just’ to characterise the importance of the total user experience, including in-app and online documentation. Historically, the two projects placed different emphasis on that and, inevitably, that still has some ramifications today.
2 Likes

Broadly speaking, we can say cabal-install and stack are frontends to Cabal . Both tools make it possible to build Haskell projects whose sets of dependencies might conflict with each other within the confines of a single system.

I appreciate that answer is 2017, and things might have changed since. But there’s plenty of confusing-them q’s on SO and reddit; preferences seem to have changed over the years; one tool has caught up/got ahead of another; then the position reversed. (Or perhaps the answers mean that one tool is a better fit to a particular way of working – that would be your “placed different emphasis”.)

These are distinctions that are going to be way beyond a newbie’s grokking. So firstly, I think it’s incumbent on instructors to make the choice and give detailed instructions to learners/set up a learning sandbox, etc, etc. Secondly, speaking for myself, I found your long answer too much in the weeds.

So I see no strong reason to use either tool. They both seem to add unnecessary complexity. All I want is programs. GHC out-of-the-box delivers that.

Addit: Also I had this in mind, from the thread we split from (thank you @atravers )

Stack … just like Cabal-the-tool, it is implemented using Cabal-the-library. Therefore, a first answer to the questions at hand is that stack is Cabal: …

Again that’s old: 2015. If what it says no longer holds, perhaps we should enter a caveat on the original thread?

I could believe one tool is more friendly for newbies. I’m also nervous that having started with one tool, it’s awkward to switch to the other. This is a bunch of considerations we ‘just’ shouldn’t inflict on a newbie to puzzle out.

[end of Addit]

I wrote this script to be a more contained cabal install --lib. It means the environment file is local to a directory.

#!/bin/bash

arch=$(uname -p)   # -m? -i?
os=linux
gv=$(ghc --numeric-version)
cabal install --lib --package-env=.ghc.environment."$arch-$os-$gv" "$@"

Oh haha I now see --package-env=. is much simpler.

Still, I will never be able to remember the spelling of --package-env.

This is not the main point of this message, but I want to loudly disagree.
When I was learning Haskell at the university in 2014, neither me nor any of my colleagues ever managed to use cabal v1-* commands for anything. Neither project or ghci based workflows. It was the main reason we were all using stack and telling everyone else, stack is the only usable tool.

Aside the random anecdote, I just want to emphasize cabal-v1 was not fine/good or approachable for newbies.

However, I did come around to the concept of sandboxes in general with a streamlined (e.g., dedicated) UX and simplified experience. I can imagine how this would be quite nice in practice, especially for newcomers.

7 Likes

Correct, v1 without sandboxes is horrible.

That is why it totally escapes me why they were removed. To me that is by far the biggest mistake that cabal has made.

1 Like

FWIW if you add —store-dir=$PWD you have basically reproduced sandboxes. This was the realisation that @hasufell and me had at ZuriHac earlier this year.

3 Likes

Thanks Andrea. Is that trick widely disseminated anywhere? On a straw poll of StackExchange:

  • There are approximately a gazillion q+a talking about cabal sandbox (I’m not saying they’re complimentary.)
  • There’s one matching cabal "store-dir"; it’s not that trick.
  • (Indeed it’s asking how to uninstall a messed-up repository. I’m alarmed to learn cabal doesn’t do that.)

Googling shows lots of people wanting to know where sandboxes went; an RFC to re-introduce them; nothing re store-dir explicitly telling of this trick.

Perhaps there are downsides? Like it duplicates your whole setup in each pseudo-sandbox – which might or might not be what you want.

I do not know whether it is widely known. I found it interesting because it seems to imply that the v2 code-path in cabal-install is not inherently incompatible with the sandbox workflow. I am convinced that someone with a good vision could implement a MVP cabal-sandbox tool in a few weeks.

I want to stress that “a good vision” is the strongest requrement; as your question aptly give away. Let me expand:

  • Recompiling everything is exactly what sendboxes used to do (AFAIK). Is that a good trade-off? Is that even a requirement? It might depend on the use-case. I don’t think it is a requirment for users interested in interactive exploration but it might be a requirement for those who want/need stronger isolation from the rest of the system.
  • How are conflicting bounds going to work? What happens if you try to install a package A that requires a new version of an already installed package B? It seems reasonable to me to update package B and everything else that already depends on it. But what if it is not possible to satisfy all constraints because the change in B is a major bump and some other package C is not ready for it? Perhaps the tool could offer the user some choices (stop / remove C / allow newer version of B?)

These are not impossible problems to solve since GNU/Linux package managers all have a solution for them; but someone has to take the lead.

The RFC mentions it many times and also outlines very precisely which v2 features are needed to emulate sandboxes: [RFC] Revive cabal sandboxes (UX) · Issue #10098 · haskell/cabal · GitHub

1 Like

I’m continuing to approach this thread with the attitude of a newbie (because that’s what I am wrt cabal/stack). So to keep it simple wrt all the good points you go on to make about conflicting bounds:

  • Expect that each sandbox will get destroyed when I’ve finished playing in it; therefore
  • don’t go trying to entangle one sandbox with another even if they’ve got largely the same content – that’ll mess up when I destroy the first one. So
  • Whether sandbox S2 wants the same or a different version of package A compared to the already-downloaded package A in S1, we don’t care:
  • Install package A in S1; install a possibly-different version package A in S2. (That’ll need compiling twice.) Disk is cheap and plentiful. (Caveat below)
  • But disk is not limitless. There must be a way to completely obliterate a sandbox and everything entangled with it, whether or not in the (sub-)directory(s). (?The RFC’s cabal sandbox destroy achieves this?)
  • Caveat from an earlier comment "Inflict it on universities that don’t want to spare 1 TB on all the students combined naively downloading packages into their user folder? No. ". Ok I get the problem: 40 students x 12 sandboxes over a semester; each with largely the same content of utility packages.
  • You’re teaching on GHC at version (say) 9.6: recent but stable/not bleeding-edge. That in effect freezes the versions of the utility packages. Put them in a common place once and make that read-only. Can cabal get configured so each student’s sandbox looks to that before dragging in another copy?

(Probably all my scenarios are answered on that RFC. But most of it went over my head.)

Hmm maybe my bad. But I’m a newbie. Most of that RFC could have been written in a foreign language for all it meant to me – indeed cabal commands are a foreign language. And the specific “this trick” —store-dir=$PWD doesn’t appear. I do see “doesn’t seem to be supported”; whereas I took Andrea’s suggestion to be something that works today(?)

You quoted half of the sentence:

store-dir: .cabal-sandbox (this doesn’t seem to be supported yet through the cabal project file)

And further down in the thread the following ticket is linked: Support `store-dir` and `package-env` in `cabal.project` · Issue #10184 · haskell/cabal · GitHub

Which is a feature request; so it’s not implemented as yet(?) So “doesn’t seem to be supported” (yet ?)

Then we seem to be back near-enough at the beginning: “Is cabal-install stable enough yet [and with suitable features yet] that GHC should be inflicting it on newbies?”

Or are you saying it’s reasonable for newbies to have to remember to put —store-dir=$PWD on everything they’re doing? And if they forget just one time, what happens/have they banjaxed their sandbox? Please explain to me as if to a newbie who doesn’t know cabal (because I don’t). And is this specifically cabal-install (the tool) or stack or cabal-the-library?

We’re going in circles. I answered that already:

v2 is a workflow that’s fine for Haskellers who deal with projects anyway and have enough time and energy to work around cabal’s bad UX.

v1 without sandboxes doesn’t work well, so now we have the worst of both worlds.

1 Like

When it comes to teaching, I now encourage the use of stack with the recommended GHC (9.4, lts-21.25) and package.yaml files. The latter are leaner than .cabal files and thus better suited to throw-away programming (such as solving exercises), also, they just follow standard YAML syntax.

3 Likes

I wonder whether people so fervently arguing in favor of sandboxes actually used them while they were available in Cabal. Because in my experience sandboxes were very annoying to manage, and the moment Stack arrived in 2015 it won the market overnight by obliterating them with “nix-style builds”, similar in spirit to what cabal v2-build introduced couple of years later.

2 Likes