The core idea of Nix that has basically "solved this problem" is simply trying to control for all possible inputs to a build-time and run-time environment, and lock them all down with hashes, which is in essence basically treating a build like a pure function. (In theory, this should result in deterministic builds and deterministic runs. And in practice, nearly 100% of the time, it does.) The point of a "derivation" is to provide that for code that does not. Nix, and derivations in general, are thus sort of a "scaffolding" over all the existing build tool and dependency managers out there that bring them "over the line" regarding this. If these build tools and dependency managers all embraced the Nix way of specifying dependencies, and they all agreed to store it in a Nix store (i.e. a Merkle tree), then hypothetically, Nix would not even be necessary (except perhaps as a group of small tools to manage the store).
1) This is probably too much to ask of people. 2) This still leaves behind decades of software that would still need to be built in the future and would thus still need something like the "scaffolding".
But again, the fundamental idea is really just this: Treat builds and runs as pure functions. Every other advantage derives directly from that principle. If someone else can figure out how to do this as simple as possible, I'm all for it! In the meantime, I think every developer should read Eelco's thesis paper on this idea: https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf
Of course, the OTHER way to solve this problem is just to statically-compile everything, leading to an explosion of disk-space usage. And even then, you wouldn't get guaranteed rebuilds.
I understand why it's a great theoretical solution, but my point is that if hardly anybody is using it, then it hasn't solved the problem, because most people are still experiencing the problem. It doesn't really matter why it isn't being widely used, just that it isn't. Like, if it were the opposite, a very poor theoretical solution to the problem that is very easy to use, but nobody used it because it just didn't solve the core problem well enough, that would also clearly not be a solution. A solution requires both things, it must be both fit for purpose and usable.
That’s just it. Nix has been growing significantly. A third of its new users were gotten in 2022, the year after I FINALLY joined the club (after scoffing at it for... at least a decade? I was one of you, basically...).
Have you worked at a startup? Do you know what a “hockey stick” growth curve looks like? Because Nix may be on the cusp of one.
Its package repo (check out search.nixos.org) has more packages that are ready to download and run than any other Linux distro, while having fewer maintainers than most distros. If nothing else, this alone speaks to the power of deterministic builds and runs. When something doesn’t randomly break, turns out that it needs much lower maintenance and thus fewer people…
The funny thing about NixOS (and I heard about this before I experienced it, which I found intriguing at the time and which I can now say is very real) is that the second you "grok" it... you will want it on ALL of your machines
So when I dove in, I said "I'm going to figure out how this works and then simplify it." Unfortunately, the closest I've come to that so far (and this is partially due to... having a 2 year old and working at a startup) is this commandline wrapper that makes most of what I need Nix to do, easy: https://github.com/pmarreck/ixnay
I still don't understand the entirety of the Nix language, but this is an excellent, excellent interactive tour: https://nixcloud.io/tour/
1) This is probably too much to ask of people. 2) This still leaves behind decades of software that would still need to be built in the future and would thus still need something like the "scaffolding".
But again, the fundamental idea is really just this: Treat builds and runs as pure functions. Every other advantage derives directly from that principle. If someone else can figure out how to do this as simple as possible, I'm all for it! In the meantime, I think every developer should read Eelco's thesis paper on this idea: https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf
Of course, the OTHER way to solve this problem is just to statically-compile everything, leading to an explosion of disk-space usage. And even then, you wouldn't get guaranteed rebuilds.