Hacker News new | ask | show | jobs
by fiatjaf 2056 days ago
I've tried many times. I read the entire manual. I would love to use Nix.

But it's too complex.

I guess that's the result of them trying to do everything an OS does using their new arcane Nix language. I don't know how else this could be accomplished though -- but I hope there is another way.

I find it weird often I would find files written in the Nix language in minified/unreadable way fashion in parts of the system.

It's a sympton of the complexity of everything that for every weird error that I would find I would search the internet and not find a person with the same problem. It's always something slightly different and then the solutions proposed to that person would made no sense to me at all or they would introduce much more complexity.

1 comments

I don't think the problem is really complexity. It's just the config language.

If you come from a Haskell background its nice, otherwise it's "arcane".

Try Guix-SD.

Actually, unlike most DSLs, the nix language itself is pretty great and can be learned in an afternoon by any competent programmer, no Haskell background needed.

The problem absolutely is complexity, and there is a lot of stuff you need to grok to be able to use nix productively in anger and sadly that includes a lot of stuff that really ought to be much more straightforward.

Also, IMO you don't do anyone a favor by recommending they try Guix-SD over NixOS unless you also make it pretty clear that Guix is quite fringe even compared to Nix. For example Nix can and is being used for Real Work by well known companies. It as a steep learning curve but also, for certain tasks, an enormous payoff that justifies this effort.

> For example Nix can and is being used for Real Work by well known companies

Real Companies are using Guix for Real Work too.

Perhaps Guix is "fringe" by some definitions, but you made it sound like some barely-usable hobby project.

To me, as a former Nix contributor, it largely boils down to a matter of taste. But there are distinct advantages (and disadvantages) to both.

I'd be curious to hear your perspective as someone who is quite familiar with both Guix and Nix. What sort of companies do you know that are using Guix for Real Work (in some significant capacity)? What would be a rational reason for using Guix in production vs nix?

Nix is used by a couple of well known companies such as Pinterest and Target, I have used (and continue to use) nix myself professionally and I know several other places that use it. But even with nix, there needs to be a really good justification to use it in preference to some more standard solution. For example, if all you are working on is python webapp with fairly simple dependencies, I'd probably recommend sticking to poetry and maybe a docker container for your DB. If you need to deal with e.g. machine learning or video processing, or something else that involves a lot of gnarly C/C++/Fortran dependencies or if you've got non-trivial DB migrations or other dependencies which you can very conveniently deal with as a (correctly cached and therefore instantaneous) build artefacts with nix, nix can start to make sense, especially if you need to customize any aspect of the build. At the point where you have a bunch of different services written in several different languages, and your dev env needs to run a dozen plus different services together plus some DB(s) and other infrastructure, you can literally achieve two orders of magnitude improvements in key metrics compared to "industry best practice" cruft like docker or (barf) minikube (e.g. how long it takes to spin up all those services correctly, CI speed, deployment times or how long it takes to spin up a new developer, how much extra tooling infra you need to shepherd and so on). Even then you will still need at least two people with a good familiarity of nix and invest in some basic training for the rest of the company and you might periodically run into annoying speed bumps.

In summary, as a rule of thumb, I'd say even something as non-mainstream as nix only make sense if you think it'll buy you a 10x or greater improvement for something you really care about. I'm not deeply familiar with Guix, but my superficial impression is that it's a much more ideologically pure and not particularly inspired transliteration of nix to scheme that keeps a lot of the obvious flaws in nix (e.g. not using principle of least power; stuff like sha256, github urls and revs should reside in toml or similar and not be munged into the turing complete and non-machine editable nix/scheme code). It still has a significantly lower user base and the greater ideological purity means more stuff won't work compared to nix or mainstream solutions. This all matters less for personal use, where I agree it is indeed a matter of taste. But to me the aforementioned means there would need to be some massive benefit of Guix over nix to make it worth considering in a professional setting. Is there, in your opinion?

There are quite a few HPC clusters that are powered by Guix:

https://hpc.guix.info/about/

Whether or not these institutions qualify as Real Companies is up to you. Other than that I occasionally see focused patches and bug reports from people using their work credentials, but nothing on the scale of Pinterest and Target of course.

We did recently get a bugfix for 'guix system container' from Google, but I suspect that was more the result of an evaluation than anything else:

https://issues.guix.gnu.org/43540

As for benefits in a professional setting, there are a few design (and implementation) differences that I think gives Guix an edge. One is grafts: Guix can deliver security updates for core packages really fast, whereas Nix needs to rebuild every dependent package. The grafting mechanism can also be used to perform other transformations, e.g. to locally enable CPU optimizations for low-level libraries without having to rebuild the world.

On the topic of security, Guix has a strong focus on bootstrapping, meaning that e.g. the Rust and Java compilers are built purely from source code, whereas Nixpkgs use opaque binaries provided by upstream projects. This property (as well as excellent cross-compilation support) is why Bitcoin chose Guix to build their installers:

https://bitcoinmagazine.com/articles/guix-makes-bitcoin-core...

Another important design difference is gratuitous use of so-called "search paths". I noticed one common criticism in this thread is that packages often needs patching to work in NixOS. In Guix, such cases are very rare. Take a look at the patches carried by Guix, conveniently stored in a single directory:

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages...

By and large, these are just security- or bug (often test suite) fixes. I won't go into detail on how search paths work, but if you try Guix on any distro (maybe except Guix System) you'll quickly understand.

It's funny that you mention "non-machine editable Scheme code". In the Lisp world, code is data, which powers among other things the "updaters" in Guix: 'guix refresh -u foo' will update the "version" and "sha256" fields of "foo" in your git checkout.

Finally, a huge selling point for me personally, is general scriptability. I recently added code to build Chromium extensions with Guix. It was about 150 lines of code, and packaging extensions is pretty much like packaging anything else:

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/build/ch...

https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages...

There are many other things of less importance that makes me stick to Guix, such as running the test suites of most packages, largely preventing compatibility and other run-time problems that occasionally show up in Nixpkgs (and even popular distros like Arch).

Now, the end user experience of Guix System is not great due to lack of proprietary firmware, as well as GNOME and KDE maintainers, but as a professional tool Guix is really solid in my (supremely biased) opinion.

Thanks for taking the time to write a up a detailed and informative answer!

I agree wrt desirability of grafts as an escape hatch (I think there's been some undocumented crappy version of this in nix for ages, no idea what keeps it in limbo). I also agree that bootstrapping is better in principle.

The search path (in nix?) thing, I don't fully get -- can you expand what you mean? Concerning not needing to patch upstream -- the world is full of setup.py scripts and other cruft that tries to download random stuff from the internet or write and read hardcoded system paths -- how do you deal with that?

> It's funny that you mention "non-machine editable Scheme code". In the Lisp world, code is data

One of the ego-salving lies lispers like to tell themselves ;) If it were so they'd enjoy world class refactoring, whereas in reality they can't even auto-indent code without manually futzing around with symbol properties in emacs. I haven't fully traced how guix update works, but looking at edit-expression it doesn't look very code-is-data to me (the replacement function operates at character not ast/sexp level; read is only called for side-effect as a hack twice).

Sure.

I was just talking from my perspective. And I found Guile much easier than Nix.

The complexity difference of NixOS compared to, let's say, Arch felt like Git to Subversion. It makes totally sense to me that a fundamentally different model of package management would require some rethinking, but it didn't make sense to me to create such a strange language for it (like Guix has proven).

I think if you're setting up a personal machine, your reasoning completely applies and a fairly superficial difference, like scheme being a more familiar language can indeed make a big difference. But I think NixOS or Guix-SD vs Ubuntu or Arch as your daily driver is mostly window dressing, you will not unlock significant productivity benefits by this choice alone unless you leverage it for setting up e.g. a unified dev/ci/prod setup with reproducible builds. At least streamlining artefact creation is where the real productivity benefits tend to come from in my experience.

However, from my own production experience with nix I find that language related overheads and frictions are just completely in the noise compared to grokking e.g. the many different flavors of overriding stuff or working out good workflows for pinning and bumping nixpkgs and individual dependencies, providing suitable overlays and integrating native language tooling (poetry, yarn, cargo etc.) with nix etc. etc. Now the language itself does have some psychological effect on wider adoption, but effectively scheme is equally obscure to almost any target audience and, IMO, an inferior design for this problem space, that presents a larger rather than smaller hurdle for most people. I guess the debugging experience at least must be better?

Don't get me wrong, I'd prefer 99% of shitty DSLs (cmake, make, pom, jinja, moustache, chef and so on and so forth) had just used even a mediocre internal lisp/scheme DSL. However, I'd say Nix is a bit of an outlier: it's IMO a remarkably elegant design that really pulls its own weight. Most of my complaints (poor debugging experience and error messages) are quality of implemenation rather than language design as such – I am not quite sure to what extent this applies to lack of static typing.

In any case one of the main usability defects of nix is shared by guix: 90% of cases should be declarative toml or similar, not some weirdo turing complete language. It's great to have a powerful language for the bits that actually need it, but a lot off stuff really shouldn't. In particular mixing metadata (description, hashes, version numbers, urls etc.) with build descriptions is just a dumb and painful way to do things and completely screws up tooling. There are tools to help with that (e.g. niv), but this should just be fixed at the source.

The language doesn't matter. It is actually very simple and nice (I read the manual, did the tutorial).

You still have to learn all the thousands of obscure schemas each thing expects and supports.

Could be written in JavaScript and you would still not know what is going on and would have to waste months in documentation and support forums.

Or maybe the documentation is just very incomplete, I don't know.

I am pretty sure moving from a DSL based on Haskell to Guile isn't a "step up" for most people.