1. 32
  1.  

  2. 11

    After reading the list of perks, I immediately thought of NixOS, then I read this bit, which summarizes everything up nicely:

    Guix is a fork of Nix and addresses the main issue that Nix didn’t get right: instead of comming up with a homebrewed domain-specific language (DSL) with its own set of limitations and idiosyncrasies, Guix uses a full-fledged programming language. (And a good one at that, since it’s Guile Scheme, a Lisp-based language.)

    So it’s basically Nix but with a different configuration language. That’s not necessarily a bad thing.

    1. 11

      I’ve never seen the following raised yet, but I personally find the Guile vs. Nix DSL argument not that clear cut. As much as I respect, and theoretically admire, that Guix is using an established language (Scheme), I do also observe some disadvantages of this choice. For me personally, they actually make me prefer the Nix DSL as of now! Specifically:

      • For a person who does not already know Scheme, I find the path to learning Nix DSL much easier! In particular: to learn Nix DSL, I just need to read a few sections in the Nix manual; personally, I found them simple, small, and understandable (at least with some initial knowledge of general functional programming that I had). Also, there’s a complete reference of available builtin functions in the manual. Whereas, to learn the Guix dialect, as far as I believe, I’d have to:

        1. First, learn the whole of Scheme. I hear there are some numerous versions/editions of Scheme (RnRS), so I’d have to first find out which of them is the version relevant to Guix/Guile. This would probably also have to include some notable part of the standard library (potentially completely irrelevant to the Nix/Guix use-case). And this learning would be done on use-cases completely disconnected from my expected eventual domain of Guix, thus already feeling dangerously boring to me.
        2. Then, learn the differences between Scheme and Guile. I presume every implementation of Scheme has some differences from The Standard, based on my general experience with programming. And unfortunately, such things are usually introduced exactly one way, which can be somewhat ironically summarized as: “You know this big, difficult thing there? You got it, finally? Great! So, you see, we are not [really] this thing.” I.e., you have to throw away some of the effort and knowledge you spent before, to re-learn some new idiosyncracies. Guile seems no different here, based on the manual, as well as some quick googling.
        3. Then, finally, learn the differences between pure Guile and the Guix dialect. A.k.a. the Guix API/framework, I suppose.

        For me personally, not knowing Scheme, I find the outlook of the path I outlined above much more daunting, than just understanding the small, focused Nix DSL guide in the Nix manual.

        Notably, to some extent, I think this part of the issue could potentially be mitigated. I believe the Guix manual could try to have a section similar to the Nix manual’s one, attempting to explain the Guile language from the basics, with focus on Guix usecases. I haven’t found such a one in the Guix manual, though I only skimmed it, so I may have missed it. For now, I presume that Guix authors would probably be rather strongly opposed to adding such a guide, per the DRY principle, a.k.a “why try to write a full Guile manual, when we can ‘just’ redirect to the GNU Guile manual?” Which sounds perfectly reasonable from engineering perspective… but does bring the unfortunate learning disadvantage I tried to describe above.

      • By using a standard Scheme language, I presume Guix automatically by definition takes the additional baggage of using an old language; with the pros come cons, such as the legacy of car, cdr, and more. Don’t take me wrong, I’m aware they are “just a cost for learning a super powerful language”, that is Scheme. But they are still a cost! The Nix DSL, by being designed from scratch, is able to break free from some of that stuff.

      That’s what I see with my mind’s eyes every time I think to myself that learning Guix would be really interesting. And as of yet, this feels too much for me.

    2. 6

      I’m surprised no one has jumped on his list of “projects using self-rolled DSLs or too-limiting programming languages”. While many of those might be better off without their own DSL, I find it hard to imagine that programming languages like SQL, R, or even sed would be better off without their own DSL. I feel like that’s the equivalent of saying “Rust would have been much better off if it used python instead”. That doesn’t make sense.

      1. 2

        Totally agree. Not to mention that it would be pretty undesirable, in general, to replace things like HTML and JSON with a general-purpose programming language.

        1. 1

          Taking issue with “self-rolled DSLs” doesn’t mean that everything has to be a general-purpose programming language. The author uses the example of the rx macro in Elisp, as an improvement over “regular” regular expressions (encoded in strings). Lisp environments make this easy with symbolic macros and the ease of writing one’s own evaluator, as opposed to tokenizing, praising and interpreting DSLs for every sub-language one would have, which I guess is what was meant.

      2. 4

        Sounds pretty awesome. Is it ready for every-day/production use? Looks like GNU Shepard is in alpha? Soooo I’m guessing not…?

        1. 7

          “As of version 0.16.0, the Guix System Distribution (GuixSD) is not production-ready.”

          https://www.gnu.org/software/guix/manual/en/html_node/Limitations.html

        2. 4

          I really want to like systems like this and Nix. However having used NixOS on my main machine for a year, it always just felt like it got in the way of getting things done. I had looked into Guix a few times before and even have a GuixSD VM that I still have yet to actually do anything with, but I guess I haven’t gotten into it far enough to tell if it solves any of the problems I had.

          (Sorry, this comment got really ramble-y here, skip to the last 2-3 paragraphs if you’re not looking for my life story as told through my adventures with NixOS.)

          The biggest issue I had was that I wasn’t looking to be a package maintainer, but if I was doing anything either off the beaten track or with really new software I had to be one. I started giving this a try for awhile, but I never managed to successfully write a nix package definition.

          As an example, the package for luasocket on Lua 5.3 is misconfigured, it needs to be built with -DLUA_COMPAT_APIINTCASTS, I spent hours, on several different occasions trying to figure out where I needed to add that, but the descriptions of all the build stages in the manual didn’t really make sense to me, and I never did find somewhere to put it that would just give that flag to GCC.

          I also tried packaging a static site generator which was written in Rust. IIRC the problem I ended up with there was that it depended on a newer version of some crate than was in the nixpkgs repo. (My understanding of how that worked is that all of crates.io got mirrored into nixpkgs occasionally and there wasn’t really a way to do it manually, or maybe that was just highly discouraged.)

          This one I really don’t even remember what I was trying to accomplish, but I needed a newer version of a dependency, but updating that broke something else. While Nix and Guix both talk about older versions always being available because you have the hashes, with Nix at least because there was only ever one of any given package (super large packages like gcc which had several major versions not withstanding) presumably you had to resolve that so that the packages as defined in the HEAD of nixpkgs still worked.

          Based on the article, at least the last one might be solved, can anyone confirm that? Does the main source of truth (git repo?) for Guix packages support having multiple versions concurrently and how long do those stick around (without having to go search though git history to find them)?

          And, to me, this all is just overhead in what I needed to do get get an environment setup so I could actually work on the things I wanted to work on. I originally installed NixOS because I thought it would save me time, I would never accidentally break something and have to spend a bunch of time when I least wanted to fixing a boot issue with my machine. While it fully delivered on that specific issue, it ended up causing most of my new experiments to be consumed with an over abundance of yak-shaving. I ended up abandoning a bunch of projects I wanted to work on, until I realized that was really unproductive and just installed PureOS (a Debian deriv). I’d much rather deal with a few hours a year of fixing my OS after I break it rather than just being unable to get certain things done.

          Please don’t take anything here as me totally blaming any of this on the Nix (or Guix) project. I really just assume they’re not to the point of being idiot proof enough for the level of idiot I am. :)

          Finally, I’m curious if there’s anyone here who would be willing to share their Guix experience, who (1) has used Guix in some not-insignificant way, (2) hadn’t used lisp before starting, (3) doesn’t use emacs, and (4) didn’t have much experience with packaging/managing software (aside from some basic ./configure && make && sudo make install manual installs) before starting. I really want an OS that has the benefits of Guix and/or Nix, but I’m not willing to put up with the current down sides I experienced with NixOS. So, I’m wondering if anyone here has had good experiences with Guix(SD) while not being the most experienced with all the different existing Linux build processes.

          1. 2

            Guix channels advantageously replace Arch Linux’ AUR and Gentoo’s overlays, allowing anyone to distribute their package definitions from, for instance, Git repositories.

            Here’s a nonfree Guix channel that I made: https://github.com/aterweele/tarsnap-guix-channel

            1. 2

              What does declarative mean in this context/how is Guix more declarative than alternatives? The term is mentioned twice, in ways that don’t really convey anything to me.

              1. 4

                You declare your system configuration and the distribution tools take care of realizing it.

                The most obvious example is that you maintain a list of packages to be installed, instead of running “install” and “remove” commands—but it goes deeper than that.

                Take a look at the manual’s examples of system configurations.

                1. 3

                  Yeah, “maintain a list of packages to be installed” is great. I am doing that on Debian with apt-mark and it’s so much better than installing and removing packages.

                  1. 3

                    I guess I should’ve been clearer: I have an idea of what that means, but how does that relate to everything about using scheme and hating on DSLs? Unrestricted scheme isn’t declarative in the programming language sense. Is this just a case where there are two unrelated meanings?

                    1. 1

                      The thing that gives LISP’s their power are that the code is simultaneously an easy-to-parse, data structure and an executable program optimized for handling that data structure. It’s why language extensions are so easy that people throw DSL’s around in LISP’s/Scheme’s. Wise programmers restrict their use a bit, though, just to keep the programs maintainable. Especially by other people.

                      Although I don’t know Guix, I imagine it takes advantage of the fact that Scheme can describe structures (eg builds), issue commands, and simultaneously be as easy to parse and interpret as a basic, configuration file. People that know it would have to chime in to tell me if my intuition is correct.

                2. 1

                  Also who needs such a system if everything goes fine? Of course things happen to not follow the plan in IT.

                  The point is if you handle further more complex situation, people (software engineers) will freely get things more complex while simple tools could have done the job.

                  What about this instead of custom shebangs?

                  /bin -> /nix/current/bin
                  /lib -> /nix/current/lib
                  /usr/share -> /nix/current/share
                  /usr/include -> /nix/current/include
                  /usr/man -> /nix/current/man
                  

                  With current a symlink to the current version of the system.

                  Then no custom shebangs are needed.

                  This start to looks like a symlink party!

                  On the other hand, I like that this is a rather stateless way to manage packages. Instead of databases fies that con get inconsistent with the real state of the system, this puts all state to the file system itself so it always is consistent.

                  1. 1

                    NixOS, and I would guess GuixSD too, exposes /run/current-system/sw/{bin,etc,lib,sbin,share} where current-system is just such a symlink. Users then get PATH set to include that bin and sbin.

                    These systems also make sure that /bin/sh and /usr/bin/env are in their POSIX-defined locations:

                    $ ls /bin
                    sh
                    $ ls /usr/bin
                    env
                    

                    So you can use those in shebangs.

                    1. 1

                      At least this is a constant path. I’ve also seen shebangs with hash in them though.

                      Probably so that scripts use the particular version of the perl/python/ruby/php/… binary they have been tested with.

                      1. 1

                        Yes, scripts installed as Nix/Guix derivations indeed have all paths to binaries—including shebangs—hardcoded to specific versions in the Nix store. As you suspected, that’s a big part of how the system guarantees the integrity of package dependencies.

                        In typical situations all the packages installed on a system will point to the same version of (e.g.) bash. When a new bash version is made default in the package tree, the system upgrade will reinstall packages that depend on bash pointing them to the new version. But it’s possible, and sometimes very useful, to have packages pointing to completely different versions.

                    2. 1

                      Note that global symlinks like this only work if you have a single profile in /nix/current. Using Nix and Guix, different users can have completely different package sets ‘installed’ in their environments. You can also launch a “shell” which contains a different package set, which is really handy for development / testing.

                      1. 1

                        I guess this also plays nicely with chroots.

                    3. -2

                      So…it sounds like the main thing here is package management. Why do I care about complex package management when I have docker?

                      As to keeping things under version control, I have configuration management.

                      What’s the advancement here?

                      1. 20

                        Docker is tremendously complex to run at any sort of scale and introduces a bunch of concerns for an application that may not be necessary. And its original purpose isn’t really to make package management easier, its to isolate processes securely. As such, it tends to be terrible for package management beyond anything trivial, which explains the glut of tools for provisioning containers. (Packer et. al.) I prefer using tools that are built to solve an issue specifically.

                        1. 12

                          Why do I care about complex package managers where I can put an entire operating system in a jail, where I would still have to worry about complex package managers but now once removed.

                          1. 10

                            Docker is addressed in the OP, but essentially Docker container builds are not reproducible. Guix packages have all software dependencies hashed into the build, so they theoretically will never break (I say theoretically because the software is still in alpha), and the system can always roll back to a working version if an update goes south.

                            1. 9

                              Docker is an attempt to solve the same problems, but it does so in an unprincipled way, and as a result it just doesn’t actually solve the problem in a way that’s consistent or reliable.

                              1. 4

                                It never struck me as much of a package manager— I have always thought the intent behind docker was to provide process isolation without the overhead of a VM. Especially since the Dockerfiles are written in an anemic shell script language.

                                1. 5

                                  If you attempt to perform builds, then you need to manage packages, whether that’s your intent going into it or not.

                            2. 4

                              What I took away was that the main benefit, apart from the virtues of functional package management, is uniformity, as the entire system is managed with Guile. I haven’t used Docker, so I may be incorrect in stating this, but I do not think Docker applies to some of the use cases listed in the article, such as configuration of the Linux kernel.

                              1. 4

                                To he it’s the prospect of stability that doesn’t conflict with novelty. The classical dichotomy between the two can be seen between something like Debian Stable/Cent OS vs Debian Unstable/Arch, where the latter might update their packages quickly, at the risk of an increasingly wobbly experience, while the former insist on waiting until experience and failure of others indicate safety. Being able to revert any change means that I don’t have to commit a leap of faith when updating, since it’s Ctrl-Z’able and can be fixed, within the intentionally conceived framework (as compared to downloading .deb packages from the internet and manually installing them).

                                The new Libre Lounge podcast talked about a “security”/“ethical” issue in their second conversation, comparing it to other package management systems like NPM on the one hand (as a generally bad example, think of “left pad”) and other containerized (Docker, but also Flatpak or Snap, which (they claim) was intentionally developed to also serve the distribution of propitiatory software).

                                Guix specifically (besides being very close to the FSF) has the interesting aspect of being written in (Guile) Scheme, with references and connections to Emacs –> the system in geared towards an open mentality and encourages to use the rights that free software grants it’s users. You don’t only have the permission to download, read, edit and share changes, but the system gives you the tools and the environment to easily hack for yourself – without having to manually run make or ./configure hundreds of times, installing each dependency one by one, hoping it’s the correct version.

                                I don’t know if this is that convincing, but I rather like this: https://www.gnu.org/software/guix/manual/en/html_node/Using-the-Configuration-System.html#Using-the-Configuration-System + https://www.gnu.org/software/guix/manual/en/html_node/Bootstrapping.html#Bootstrapping. When everything can be reproduced with minimal dependencies (aka. binary seed), that tries to result in the same systems over different platforms (x86 vs RISC V, Linux vs Hurd, Laptop(s) vs Desktop(s), …), I’d be interested in using something like that, and I guess others would too.

                                1. 1

                                  None of the advantages and features listed in the article interested you?

                                  1. 0

                                    Not as compared with existing tools that already solve these problems. It seems like the author of this article hasn’t used configuration management before and is blown away by it.

                                    1. 12

                                      Is there another distribution except NixOS that lets you roll back your whole system configuration? That does system upgrades atomically? That lets you say “install my same system configuration but using the packages as of August 15 last year?” That lets non-root users install packages? That can take your system configuration and automatically generate a QEMU VM or a USB live disk? That can generate Docker images in a way that’s fundamentally more composable and reproducible than docker build?

                                      1. 10

                                        There’s a thing that Nix users like to do, which is to classify infrastructures into one of three categories: divergent, convergent and congruent.

                                        Divergent infrastructure is what you get when you have no CM. You run arbitrary commands on your systems, you hope you remember what you did, even when do you manage to stay fairly consistent you probably have differences between boxes A and B because you ran apt-get update at different times

                                        Convergent infrastructure is what you get with Puppet or (I believe but have not verified) Chef or Ansible or similar: there’s some kind of description of the parts of the system that are “managed”, but it’s sufficiently broad-grained that there may be differences lurking “under the hood”: files that the CM system doesn’t know about may have been updated, rewritten or abandoned by any installed package or previously-installed-but-since-removed package so who’s to say what they contain or whether they’re identical across your fleet? Hopefully they’re functionally identical and 95% of the time they probably are, but … If you’ve ever had to run puppet twice to get the system into the state you wanted it, or had two machines be slightly different because the upstream package server did an update between puppet runs, you’ve experienced the 5%

                                        Congruent infrastructure is where, when you apply the configuration, you get the same answer every time. Nix does this; Guix (again, I assume - never used it myself) does this. If you’ve never used it before it could be confused with “traditional” CM, but I think it’s pretty next-level stuff

                                        http://www.infrastructures.org/papers/turing/turing.html - a good read

                                        1. 2

                                          A good read indeed.

                                          Though, I would assume that Traugott would be more a fan of Docker than Nix. Docker even resolves the control-loop problem by having a host. Sure you can argue that the host itself still has the problem, but still Dockerfiles are a very controlled and totally ordered way of setting up a system.

                                          Update: After some more reading, I find that congruence is not what I want for my little network at home. I want my machines to install security updates from Ubuntu automatically and asap. I do see the value for full-time sysadmins though. They have the time to check and test each update.