the "effort" is just pointing to a particular checkout from nixpkgs repo
> With flakes you can combine packages and versions explicitly.
it's the same thing with default.nix/shell.nix, just having a separate lockfile changes nothing in the underlying `builtins.fetchGit` / `builtins.fetchTarball`
In a team setting, enforcing that everyone has to follow purity best practices because nothing else is allowed is great.
purs-nix is a good example that even if per-module compilation is made into derivations, the rest of the remaining heavy-lifting of constraints resolution is done by the external build tool. You can think of Nix as a dependency manager, but only with a huge caveat that it doesn't actually manage constraints that come with those dependencies, especially transitive ones.
The original Nix thesis [0] talks about using Nix as a low-level build system in Chapter 10.1. And the author of opam-nix* has made an attempt to use Nix as a build system [1]. However, dune is a complicated bit of software that's not easy to replicate, and Nix isn't particularly well suited to the task.
[0] https://edolstra.github.io/pubs/phd-thesis.pdf
[1] https://gitlab.com/balsoft/tumbleweed
*Which is essentially functionality to use Nix as a dependency manger with opam-repository.
- Instead of channels, I use fetchGit with pinned revisions
- Instead of managing installed software via nix-env, I use buildEnv to collect everything I need in a single derivation. If I'm on NixOS I'll put that in systemPackages; or otherwise (e.g. on macOS) I'll use nix-env to only install that one package.
These have the advantage of being declarative files, which can be tracked in git; rather than imperative commands.
It's not in official documentation but the biggest reason is it's not reproducible by default and a new user could easily not pin nixpkgs, then think "wait... Nix isn't reproducible".
nix-shell and niv or otherwise pinning nixpkgs is pretty good, though there are some reproducibility advantages flakes has over nix-shell + niv such as:
- not allowing access to files not tracked in the git repo - forcing the user to lock their inputs with flake.lock whereas pinning/niv are optional
Also see: https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure
I've used Nix/NixOS for years and still don't have a use case for flakes. I only enabled it this week to restore some functionality to the nix command, which is still a work in progress.
Getting there was painful and required a deep dive into the documentation. In the end, it was as simple as adding this line to my configuration.nix:
nix.settings.experimental-features = [ "nix-command" "flakes" ];
The flexibility of Nix is one of its main selling points, so it's impossible to say that "everyone" uses it in a similar way. Flakes are a welcome, but disruptive, enhancement. Hopefully, the experimental phase will end soon.That said, it feels like they are slowly coming to terms with it and just accepting it as default. Here are two examples of maintainers eventually accepting flake support on their repos after initial hesitation [1][2].
[1] https://github.com/tpwrules/nixos-apple-silicon/pull/47 [2] https://github.com/NixOS/mobile-nixos/pull/404
If they haven't pinned nixpkgs, I have no idea at what point it _was_ building successfully. It's just dumb luck whether my system's channel is a compatible nixpkgs.
If it's pinned, great, I can use that pin until I'm bothered to bring it back to mainline. At that point I'll override the nixpkgs input and bear the cost of updating and maintaining it.
Flakes make managing pins those easier, through a nice(r) CLI, and a standard format for them.
You'll still want dune, though I could see an argument for generating the dune files from nix expressions.
I've found quite a few articles on alternatives to nix-shell in the flakes world, but I haven't found one for this usecase (which is also my main Nix usecase).
Particularly, how do I have a flakes equivalent for nix-shell that isn't pure? It is convenient to be able to run git, or SSH or whatever from my development shell, and those things shouldn't be in my project build setup.
Question to others: as someone with Nix experience and interested in learning OCaml but hasn’t quite bit the bullet, what does dune actually offer me if I’m using Nix to manage dependencies already? It feels like adding an unnecessary layer of LISP when Nix and opam should already cover everything.