1. 42
  1.  

  2. 40

    I’m not going to excuse the ghc-pkg infrastructure, it’s not good. I’d love for everyone to move to Nix and then scrap the ghc-pkg structure (and even cabal) entirely, but that’s not gonna happen.

    My advice for the current problem is: never install global packages. Always use a sandbox, even for things like pandoc. Just put the binaries on your PATH - don’t rely on cabal to do it.

    I recommend doing the following:

    echo "require-sandbox: True" >> ~/.cabal/config
    

    That way you can’t install anything outside of a sandbox.

    There is one exception I have for this rule: cabal-install itself. When an update comes to Cabal, I update it like:

    cabal --no-require-sandbox install cabal-install
    
    1. 19

      Just to say, this comment is great and is the only one that has actually solved my issue with Cabal. If I start regularly writing Haskell again, it’s probably because of this.

      Don’t get me wrong, I still think Cabal and ghc-pkg are terrible, but the ability to disable non sandboxed installs by default means that they’re no longer actively user hostile, which is all I needed.

      1. 8

        If you’d like more examples of how to use Cabal and manage Haskell projects productively, I wrote a HowIStart tutorial here. I also wrote a quick blog post yesterday to demonstrate how I build other peoples' projects.

        1. 3

          I really liked the style of that blog post. It’s extremely rare to see the step where something didn’t “just work”, and even rarer to see such an honest approach to fixing it (“I just Googled it”). I imagine this sort of guide is really helpful for people who are just starting out programming and haven’t mastered the art of investigating and solving unexpected problems.

          1. 2

            such an honest approach to fixing it (“I just Googled it”).

            You’d be surprised how much context matters here. When I ‘show my work’ for an answer in IRC I have to be careful because people will think you’re linking Google as a means of telling them to fuck off, when really, I’m trying to show process so they know how I got the answer.

            Which is almost always: “copy and paste the words they used to describe their problem into Google, then sift about”

      2. 5

        My only issue with nix the package manager is mostly documention related. It is extremely annoying to use and setup on osx, and common use cases are either now out of date due to the haskell-ng bit, or just plain don’t work.

        That and I can’t speak too highly of the nix language though I can tolerate it now after a few months of on/off use. I love the idea of nix to be sure, but when it breaks it makes ghc error messages look sane.

        I’d much rather cabal become more nix like than ditch cabal for nix. My biggest gripe with nix is multiple versions of anything really. Again, I love nix but I can’t think of it as a panacea to haskell packaging.

        1. 5

          I’d much rather cabal become more nix like than ditch cabal for nix

          Ditto.

          Again, I love nix but I can’t think of it as a panacea to haskell packaging.

          The idea that Nix is a solution to Haskell packaging problems confuses me in part because Nix-pkgs is more of a community-wide rolling release which is tremendously awkward for programming projects.

          Lets take a look at an example of some haskellPackages:

          nixpkgs.haskellPackages_ghc741.httpDate                           haskell-http-date-ghc7.4.1-0.0.2
          nixpkgs.haskellPackages_ghc742.httpDate                           haskell-http-date-ghc7.4.1.20120508-0.0.2
          

          In real life, what version of httpDate I use is totally uncoupled from the version of GHC I’m using. And in fact, I might need different versions of httpDate compiled by different versions of GHC. This doesn’t fit how programming projects work very well, particularly in a language community that has decided dependency upper bounds are worth enforcing and maintaining.

          1. 2

            cabal2nix is the tool to generate Nix expressions for specific versions. If you want version 0.1 of dogfoo then it’s just:

            cabal2nix cabal://dogfoo-0.1 > dogfoo.nix
            

            The expression is paramterised on a version of GHC. I was really impressed when I created a .nix file which compiled a version of GHC with integer-simple instead of integer-gmp and then built a project which would have otherwise crashed when using gmp. We can’t do things like that using Cabal.

            1. 2

              cabal2nix is the tool to generate Nix expressions for specific versions. If you want version 0.1 of dogfoo then it’s just:

              Yeah except it’s never that simple, I had to make various manual edits to the output of cabal2nix, never once did just using the output work, before or after haskell-ng. That’s why Wiegley had those scripts for generating modified versions of the Nix expressions.

              What manual edits did I need to make? Who knows? The answers changed every week. I’d need to keep detailed notes of what the current Community Approved Process for getting a Haskell project built to know what I was supposed to do at a given point in time.

              We can’t do things like that using Cabal.

              Swapping in a different arbitrary-size Integer library and installing GHCJS are two places where Nix excels. Building a simple Haskell project like Bloodhound wasn’t one of them.

              Most peoples' problems with Cabal or Hackage have nothing to do with needing a slightly differently configured GHC install. All Nix helps with for most people is to have a cache for dependencies that have been previously compiled, but any time saved here will be lost to fussing with creating and installing the Nix expressions for all the library versions you have that aren’t part of the mainline package repo.

              It also does absolutely nothing to help out the Windows users for whom sandboxes aren’t as complete a remedy as they were for Mac and Linux users.

              It’s far too easy to get “stuck” with Nix and be in a situation where experienced users can only shrug and suggest that you file an issue on the Github repo with the developer. The same developer who ignored and was quite intransigent about problems with Hydra and the ancient Haddock version breaking things for Mac users which stayed broken for, IIRC, about six months or more.

              Why should I believe something else won’t break and stay broken for 6+ months again? Why would I spend my time trying to get all this stuff working when nobody can figure out why I can’t install a simple Haskell package on NixOS (not Mac, not Ubuntu - I was running NixOS natively although I tried to get it working in the other two as well).

              Much of the time I probe people about how they’re using NixOS they often sheepishly will admit that:

              1. They’re not using it for the actual Haskell builds

              2. They’re not using it for their main development machines, only as a deployment target

              Yet these same people will pop up in every thread telling beginners who’ve scarcely a need to deploy anything and just need to get something built in Haskell on their personal machines that before they can proceed with Haskell, they need to learn this other thing called “Nix” which is utter nonsense.

              Meanwhile the answer for getting stuff built on Windows/Mac/Linux has been the same since sandboxes came out over a year ago:

              cd my-project
              cabal sandbox init
              cabal install
              

              I haven’t even begun to talk about the total Hell that was getting my wifi to work (which never fully, properly worked - had to wait 2 minutes++ before wifi would “wake” on boot/sleep) on my Thinkpad w/ NixOS. A Thinkpad with an Intel wifi chipset having trouble on Linux in 2015.

              I sincerely hope NixOS improves. I liked the systemd-all-the-things setup and I liked the idea of being able to version control my OS state sorta like Puppet but even easier to use and nicer. However, it does very little for the average Haskell user right now.

              1. 1

                You used to need to edit the .nix expression but haskell-ng actually did help by allowing overriding of packages, outside of the generated file. Here’s an example of overriding the settings which prevent bloodhound from working:

                with import <nixpkgs> { };
                
                let lib = import <nixpkgs/pkgs/development/haskell-modules/lib.nix> {
                  inherit pkgs;
                };
                in
                lib.dontCheck (lib.doJailbreak (haskellngPackages.callPackage ./default.nix { }))
                
                1. 1

                  We tried using haskell-ng to build Bloodhound on NixOS too. We did the same jailbreak + don’t check + break out dependencies which need older versions. My whole OS was fucked and couldn’t build any Haskell packages. Nobody could figure it out.

      3. 9

        The Haskell ecosystem does have this habit of considering these problems “minor” (and that’s almost a quote from someone who worked on the GHC). Eco-system tending just doesn’t seem to be in the DNA of the community.

        I may be a bit of snarky, but the fact that such a fundamental type as Either is marked experimental speaks a lot about the approach to library gardening.

        https://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Either.html

        1. 2

          Almost everyone in the Haskell community sees the current package management system as a very serious issue.

          1. 1

            “Everyone” has also seen darcs as an issue, when it was still the typical VCS in the Haskell world. Sadly, it hasn’t lead to an influx of maintainers and the current state of darcs show that it could have been improved with a team effort.

            1. 4

              Yep, everyone saw darcs as an issue….. so they moved to git like everyone else. This has nothing to do with Haskell; darcs just lost.

              1. 0

                http://lists.osuosl.org/pipermail/darcs-users/2007-March/010877.html

                Now for the good: there are a lot of things about darcs that I love. I’ve grown very attached to cherry-picking and I imagine I’d be very sad to lose it. The Emacs darcsum mode is a huge win: single-keystroke ‘darcs whatsnew’, and then you get to pick hunks to commit or revert interactively. This has saved me huge amounts of time compared to CVS. And ‘darcs send’ is getting us contributions that we probably wouldn’t have had otherwise.

                Doesn’t look like it supports your statement. And I’m talking about those times.

        2. 5

          I also understand that cabal sandboxes are a thing. I don’t care about that either.

          Literally all of his issues can be fixed by using sandboxes, I don’t understand his argument that while using sandboxes you can somehow accidentally mess everything up, that has never happened to me.

          AFAIK, when you’re in a sandboxed environment Cabal will disregard your global installs when building? Maybe I’m wrong on this.

          1. 8

            I had problems when sandboxes initially came out. I’d sometimes forget that I didn’t create one when working on a new project, do a cabal install and then have conflicting global packages. I was really happen when the require-sandbox flag was added later on.

            1. 6

              No, it doesn’t disregard the global installs. It can’t, because base is part of the global installs, as are the other libraries which are required to build GHC.

              In an ideal world, one would only ever have these very minimal libraries installed globally. Even that is still a problem, because it means you incur the “why isn’t it using my newer version” problem if you ever try to upgrade one of them… The answer is generally because you transitively depend on the GHC API, which depends on exact versions of the core libraries, but knowing that doesn’t actually lead to a solution other than build your own GHC.

              As a community, these small things are hurting and they need to be much, much higher priorities to fix.

              Or move to Nix instead of Cabal. That’s honestly my first-choice outcome. :/

              1. 3

                Or move to Nix instead of Cabal.

                Cabal sandboxes have been fine for me, I’ve never once been able to get (with copious help from experienced Nix users) a simple Haskell project to build in Nix.

                No, it doesn’t disregard the global installs. It can’t, because base is part of the global installs

                OP probably meant user package-db. I should write a post explaining all this sometime - the relationship of global <> (user | sandbox) package-db isn’t very clearly explained.

                1. 5

                  “Works for me” is a very low bar. Agreed that Nix has a ways to go; that’s why it’s a pipe-dream.

                  I consider the user package-db to be global in the same way as the system package-db is. I understand the distinction, but neither is a suitable place to install anything, ever. :)

                  My problem with sandboxes is that, if I have five related packages, all written by me, which depend on each other in some fashion… and I want to make a change to one that’s high up the graph, then check its impact on the others… I wind up building a great many unrelated libraries once per package of mine.

                  Sharing a sandbox reduces this load, but at the cost of making it very easy to make mistakes as to which versions of one of my packages the others are being built against. It also still doesn’t solve the problem that there’s no real way to transitively unregister everything that was pulled in for the benefit of a later-in-the-chain package, for the purpose of getting a clean sandbox state to test the earlier-in-the-chain ones.

                  The last time I had this need was mid-2014, and nested sandboxes were being discussed as a possible solution. I’m not sure if they’re implemented yet. I think they’d solve most of my issues if they are, but would need to try.

                  1. 1

                    “Works for me” is a very low bar

                    Less so, when I’m not even really speaking exclusively about myself, but also about the >100 people I’ve helped in IRC. The only time I’ve seen sandboxes not work is a recent (~48 hours ago) case with a Windows user.

                    Agreed that Nix has a ways to go; that’s why it’s a pipe-dream.

                    The problems are not purely with implementation. There’s a difference between what people need an OS package manager to do and what people need their project dependency management to do (Maven, Cabal, etc.)

                    Example: your project uses an older version of a library than what is in the nix-pkgs repo. What do you do? You manually create a Nix package out of the version you need. What if there were problems in the past that required extra (more than the packaging itself) work to make the Nix package work? You get to repeat all that because Nix packaging isn’t designed to solve the same problem as Cabal or ghc-pkg.

                    I consider the user package-db to be global in the same way as the system package-db is. I understand the distinction, but neither is a suitable place to install anything, ever. :)

                    I tend to agree except in the case of the aforementioned Window user. They had to use their user package-db because there’s something weird going on that I need to put a repro together for. Basically GHC couldn’t “see” the packages in the sandbox path and we’re not yet sure why. Global package-db - absolutely never should that be used. Platform still uses the global package-db for non-critical stuff and it causes package conflicts for new users all the time.

                    It also still doesn’t solve the problem that there’s no real way to transitively unregister everything that was pulled in for the benefit of a later-in-the-chain package,

                    This is annoying, yes. One way to deal with this is to either change your project constraints to make things line up the way you want, or manually add the constraint, then install with said constraint (cmd line or Cabal file) and force reinstalls in the sandbox. That’ll reinstall the specific dep and the dependencies it affects as needed. If you want to force specific versions without putting them in your Cabal file, you can use a Cabal config/freeze to specify specific versions, then cabal install –force-reinstalls.

                    unregister everything that was pulled in for the benefit of a later-in-the-chain package, for the purpose of getting a clean sandbox state to test the earlier-in-the-chain ones.

                    Some of this could be addressed by having sandboxes shelved somewhere and symlinked to. Portable/movable sandboxes is one of the fixes currently being considered and would help here too.

                    nested sandboxes were being discussed as a possible solution. I’m not sure if they’re implemented yet.

                    That isn’t on deck at the moment, I don’t think the feature has any advocates and current maintainers are likely to shy away on account of apparent complexity. If you speak up in the Github project it’s possible things could change or at least an understanding of why it isn’t a good idea could be arrived at.

                    It would really help the tool maintainers a lot if they heard more from end-users, especially from people who are at least partly repelled by the current tool situation. It would help the people advocating for improvements if there was more evidence of malcontentedness with the current UX.

                    1. 3

                      Your use-case was “build one package in a sandbox with its dependencies”. Indeed this works all right (finally). Serving the needs of beginners is important. Serving the needs of experienced users is also important. That does not adequately describe what I tend to need, and I think I explained how.

                      Re: Nix not having old versions. Yes. I don’t know in full detail what a Nix solution would look like, but I agree that having all versions rather than only the latest is a requirement for it to replace Hackage, and is not currently in place.

                      Yeah, it sounds like the Windows scenario is a special case of some sort; I hope you’re able to repro it.

                      Yes, I know how to do those workarounds, and I used all of them extensively. I’m happy to not have the need at present.

                      Yes, portable sandboxes will be great, but they’re certainly several layers of architectural fix away; right now, you can’t even move Cabal-built .a files to a different directory in the general case because they hardcode the paths they’re meant to be installed at via a _paths.hs file generated behind the scenes, and there’s no way to know without reading its source whether a given library makes use of that information or not. This is unfortunately a feature that there’s no other easy way to achieve in certain situations, so it’s not clear what the fix should be. When that problem is solved, we can continue to peel the onion and fix the other blocking issues. Portable sandboxes would make me much happier but are not a short-term solution.

                      Honestly, I spoke up last year and I generally stay away from these conversations once I’ve said my piece, because the Haskell community loves to say “but you can’t do this concrete fix because of this abstract concern that only two people present understand”, and recurse on that a few times, and it’s intensely frustrating and I choose not to engage.

                      1. 1

                        Serving the needs of experienced users is also important.

                        Sure, I’m an experienced user too. I’m also working with a larger sample-size than most experienced users WRT beginner and intermediate experiences because people complain to me or ask for help in IRC.

                        Portable sandboxes would make me much happier but are not a short-term solution.

                        Oh for sure, but at least being able to say, “download this and you’ll be able to build our stuff” would be pretty cool. It also means we’d have a plausible means of providing what Platform does without polluting the global package-db.

                        loves to say “but you can’t do this concrete fix because of this abstract concern that only two people present understand”, and recurse on that a few times, and it’s intensely frustrating and I choose not to engage.

                        Yes I’ve been through this a couple times and it’s partly why I’m trying to keep my eyes peeled for people willing to help me lobby for what needs fixed. Thanks for your past efforts, hopefully the welcome mat is out next time you spend some time with Haskell.

                        1. 2

                          I’m certainly not trying to insult you or call you inexperienced; I’m aware that you’ve been around as long as I have, and I try to avoid such attacks when I spot myself making them, in any event. The examples you’re giving, of things that are achievable, do not meet my needs. I don’t think the strength of the claim that they are achievable is at issue. :)

                          Yeah… I hear that. Sympathies!

                          1. 2

                            I’m certainly not trying to insult you or call you inexperienced

                            I know you aren’t, but I sometimes experience that thing Kindergarten teachers get where people talk to them like they’re kids because I spend a lot of time teaching new people.

                            do not meet my needs.

                            I would like to understand those needs better as they are outside what I’ve run into, but it’s not my place to ask for any more of your time. What you’ve offered so far has been appreciated.

                            I’m passing out upvotes all around. Have a good day :)

            2. 3
              • tried sandboxes (doesn’t work)
              • tried cabal freeze (made things slightly better)
              • tried nix (on Mac), hard to use and didn’t worked
              • tried stackage and Haskell LTS works like a charm. Never had any more problem with it.

              So, use global conf for Haskell LTS. Easy and efficient. Think of Haskell LTS as Debian stable for Haskell packages.

              1. 2

                I used to have a lot of problems too with Cabal. I’ve been using OCaml for the past two years, and I have found opam to be a great package manager, really happy with it!

                1. 1

                  There is also the stackage stuff for confirmed cabal builds, which seems to be addressing some cabal issues. All said, I’m just a spectator in the Haskell world. It doesn’t touch uninstall at all afaik: http://www.yesodweb.com/blog/2015/04/announcing-stackage-update

                  1. 4

                    The stackage set of tools is absolutely brain-dead to use and relieves most of the problems mentioned here.

                  2. 1

                    I am learning Haskel for the sole purpose of learning Functional Programing.

                    Cabal and the lack of pathing when I install Haskell on Linux and Windows is strange.

                    That Cabal fails so often. I really have a sour taste in my mouth and I am thinking I should just learn scheme.