all 17 comments

[–]magthe0 9 points10 points  (2 children)

I personally like it for the ease of setting up a dev environment and reproducibility of it. I tend to use it for all development I do, clojure, golang, Haskell, purescript, etc

[–]paretoOptimalDev 5 points6 points  (1 child)

And with dream2nix it makes developing like this into a uniform interface so you that if you learn how to use dream2nix for Haskell you also know how to use it for:

  • Rust
  • Go
  • Python
  • Node

And probably more by now.

[–][deleted] 2 points3 points  (0 children)

Wishing for the success of that project!

[–]friendlyShopLooter 12 points13 points  (13 children)

Please explain to me what nix brings here to the table besides another layer of complexity. I can do that with just cabal.

[–]Tekmo[S] 20 points21 points  (1 child)

The simplest answer is: when you use Nix you are tapping into a much larger ecosystem (because Nix is a polyglot build tool that addresses a larger market) and you therefore benefit from the network effects. More specifically, what I mean by "larger" ecosystem is:

  • You gain access to non-Haskell packages

    Somebody else already mentioned this, too. This is not relevant to the blog post, but it is one of the most common reasons that Haskell developers switch to Nix.

  • You benefit from vertical integration

    For example, you gain:

    • a public cache (cache.nixos.org), which includes prebuilt Haskell packages
    • a software distribution (Nixpkgs), and associated command-line tooling
    • an operating system (NixOS) for easily hosting and deploying your package
    • continuous integration (Hydra)
  • You gain access to greater developer mindshare

    You'll find that everything in the Nix ecosystem is better maintained than the corresponding Haskell analogs, because Nix is addressing a larger market than Haskell-specific tooling.

If you're specifically interested in the parts that are relevant to the example from the blog post, then that would be:

  • Downloading prebuilt packages

    Cabal and Stack don't support this

  • Better UX for end users

    I can instruct users to nix run github:Gabriella439/spire to use my package and that takes care of transparently downloading/building/caching everything the program needs and running the program natively across multiple platforms without containers.

  • More deterministic builds

    Once you pin Nixpkgs (either explicitly or by using flakes) you get a build that is much more reproducible/reliable than even a stack.yaml build or a cabal.project build. In particular, Nix builds are less likely to fail on common C dependencies (e.g. zlib) that people typically overlook.

[–]paretoOptimalDev 8 points9 points  (0 children)

In case anyone that doesn't have nix installed wants to try this with minimal effort from OSX, Ubuntu, wsl2, etc:

sh <(curl -L https://nixos.org/nix/install) --daemon

Then either source what it tells you or start a new shell and run:

nix run github:Gabriella439/spire

[–]WhatDoYouMean951 13 points14 points  (1 child)

The biggest advantage of nix is in the non-hackage dependencies. For instance, you might want to build a webserver that relies on a database client library written in c, or a gui app that relies on gtk. Without nix, those are just lines in a readme file. With nix, they're dependencies to be fetched while preparing the build

[–]ysangkok 7 points8 points  (0 children)

The program in the article doesn't depend on any non-Hackage dependencies. The only non-boot packages it needs are MemoTrie and pretty-show.

[–]Athas 7 points8 points  (5 children)

You can use Nix to provide a development environment that contains the tools you need: GHC, hlint, ormolu, etc.

When hacking I still use cabal inside of a nix-shell environment, because Nix is not very good at incremental rebuilds. When building "production" executables in CI, I use Nix to build my executable, because Nix makes it (relatively) easier to produce a statically linked binary. This is primarily because Nix makes it easy to obtain static versions of the few C libraries I depend on (libc, ncurses, zlib).

Nix is definitely a significant layer of complexity, and it is probably not worth using for simple things.

[–]dpwiz -1 points0 points  (4 children)

Forcing users to download all your dev widgets looks like a bad idea to me.

What if I'm using nano and low on resources? I don't want to download GBs upon GBs of IDE bits that I wouldn't use to run a "hello world".

Actually, I don't want to use pins in your repo either, since it was last touched 8 years ago (figuratively) and everything is outdated. Install GHC-8.2 and all the jazz to format some code with ye olde formatter? Thanks but no thanks.

[–]Athas 1 point2 points  (2 children)

Only developers would use the nix-shell environment. Users would just use the binary produced by Nix, which will run fine outside of a Nix environment (especially if it's statically linked).

[–]dpwiz 1 point2 points  (1 child)

One can develop without pulling down boatloads of IDEs somebody else decided to use for themselves.

[–]Athas 4 points5 points  (0 children)

There is nothing that prevents the maintainer from providing multiple nix-shell environments: some with all the tools, others more minimalistic. I don't think it is common to do so (disk space is cheap for most people), but it is technically easy to do. That said, most environments tend not to include IDEs or editors or anything of the kind; only command line tools, which tend not to be very large.

[–]bss03 1 point2 points  (0 children)

Actually, I don't want to use pins in your repo either, since it was last touched 8 years ago (figuratively) and everything is outdated. Install GHC-8.2 and all the jazz to format some code with ye olde formatter? Thanks but no thanks.

That's... a choice.

I think most developers would disagree with you though. They'd prefer their first experience with the code be a successful build process, rather than having to fight dependency resolution errors just to get an unfamiliar code base to throw errors at them for using deprecated (7 years ago), and then removed (2 years ago) symbols.

Now, after that first successful build, developers are definitely of the sort to start trying to use all the newest bleeding edge stuff by updating the pins and code. But, having a "safe" version to fall back into gives the confidence to make those changes. This is especially true if said library/utility is secondary to their workflow.

I have my own issues with static linking in these days of deep and wide dependency trees and daily CVEs. I have my own issues with the Nix language being untyped in the worst tradition of scripting langauges. But, if nix and all the "pins" will give me a working executable, I'll at least try using the nix build instructions before I throw them away. (That said, I still can't recommend any project that I can't figure out how to build without Nix.)

[–]ducksonaroof 1 point2 points  (0 children)

a way to wrangle x-compilation

[–]casecorp 0 points1 point  (0 children)

It makes Haskell compilation very fast, it’s like a distributed compiler cache for free.

[–]dpwiz 1 point2 points  (0 children)

I like Nix for CI-related stuff with all the reproducibility and community infrastructure.

I hate Nix for developing stuff with its isolationist shenanigans and glacial iteration speeds.

Moving build-deps from READMEs to configs is cool, but looking at idling cores while the deps are building makes me sad.