Hacker News new | past | comments | ask | show | jobs | submit login
GNU Guix and GuixSD 0.15.0 released (gnu.org)
115 points by severus_snape on July 6, 2018 | hide | past | favorite | 25 comments

I ask this with no passive aggression; what are the advantages of Guix over Nix? I've used Nix a few times and thought it was pretty neat...

Here's something I wrote about this four months ago (with minor corrections). I hope this helps.


As one of the co-maintainers of GNU Guix I'm obviously biased, but here's what I consider some important unique features of Guix:

- Guix is all written in Guile Scheme (with the exception of parts of the inherited daemon, which hasn't yet been completely implemented in Guile); this extends to development tools like importers, updaters, to user tools like "guix environment", and even bleeds into other projects that are used by GuixSD (the GNU system distribution built around Guix), such as the shepherd init system. There is a lot of code reuse across the stack, which makes hacking on Guix really fun and smooth.

- Packages are first class citizens in Guix. In Nix the idea of functional package management is very obvious in the way that packages are defined, namely as functions. These functions take their concrete inputs from an enormous mapping. In Guix you define first-class package values as Scheme variables. These package values reference other package values, which leads to a lazily constructed graph of packages. This emergent graph can be used as a library to trivially build other tools like "guix graph" (for visualising the graph in various ways) or "guix web" (for a web interface to installing and searching packages), "guix refresh" (for updating package definitions), a lovely feature-rich Emacs interface etc.

- Embedded DSL. Since Guix is written in Scheme---a language for writing languages---it was an obvious choice to embed the package DSL in the host language Scheme instead of implementing a separate language that needs a custom interpreter. This is great for hacking on Guix, because you can use all the tools you'd use for Scheme hacking. There's a REPL, great Emacs support, a debugger, etc. With its support for hygienic macros, Scheme is also a perfect vehicle to implement features like monads (we use a monadic interface for talking to the daemon) and to implement other convenient abstractions.

- Graph rewriting. Having everything defined as regular Scheme values means that you can almost trivially go through the package graph and rewrite things, e.g. to replace one variant of a package with a different one. Your software environment is just a Scheme value and can be inspected or precisely modified with a simple Scheme API.

- Code staging. Thanks to different ways of quoting code (plain S-expressions and package-aware G-expressions), we use Scheme at all stages: on the "host side" as well as on the "build side". Instead of gluing together shell snippets to be run by the daemon we work with the AST of Scheme code at all stages. If you're interested in code staging I recommend reading this paper: https://hal.inria.fr/hal-01580582/en

- Bootstrapping. Some of us are very active in the "bootstrappable builds" community (see http://bootstrappable.org) and are working towards full bootstrap paths for self-hosting compilers and build systems. One result is a working bootstrap path of the JDK from C (using jikes, GNU classpath, jamvm, icedtea, etc). In Guix we take bootstrapping problems serious and prefer to take the longer way to build things fully from source instead of just adding more binary blobs. This means that we cannot always package as many things as quickly as others (e.g. Java libraries are hard to build recursively from source). I'm currently working on bootstrapping GHC without GHC and without the generated C code, but via interpreting a variant of GHC with Hugs. Others are working on bootstrapping GCC via Scheme.

- GuixSD, the GNU system distribution built around Guix. GuixSD has many features that are very different from NixOS. The declarative configuration in Scheme includes system facilities, which also form a graph that can be inspected and extended; this allows for the definition of complex system facilities that abstract over co-dependent services and service configurations. GuixSD provides more Scheme APIs that apply to the whole system, turning your operating system into a Scheme library.

- I like the UI of Guix a lot more than that of Nix. With Nix 2.0 many perceived problems with the UI have been addressed, of course, but hey, I still prefer the Guix way. I also really like the Emacs interface, which is absolutely gorgeous. (What can I say, I live in Emacs and prefer rich 2D buffers over 1D command line strings.)

- It's GNU. I'm a GNU hacker and to me Guix is a representative of a modern and innovative GNU. It's great to see more GNU projects acting as one within the context of Guix and GuixSD to provide an experience that is greater than the sum of its parts. Work on Guix affected other GNU packages such as the Hurd, Guile, cool Guile libraries, and led to a bunch of new GNU packages such as a workflow language for scientific computing.

On the other hand, although Guix has a lot of regular contributors and is very active, Nix currently has more contributors than Guix. Guix is a younger project. The tendency to take bootstrapping problems very seriously means that sometimes difficult packages require more work. Oddly, Guix seems to attract more Lispers than Haskellers (I'm a recovering Haskeller who fell in love with Scheme after watching the SICP lecture videos); it seems to be the other way around with Nix.

Having said all that: Nix and Guix are both implementations of functional package management. Both projects solve similar problems and both are active in the reproducible builds efforts. Solutions that were found by Nix devs sometimes make their way into Guix and vice versa. The projects are not competing with one another (there are orders of magnitudes more people out there who use neither Guix nor Nix than there are users of functional package managers, so there's no point in trying to get people who use Nix to switch to Guix). At our recent Guix fringe event before FOSDEM Eelco Dolstra (who invented functional package management and Nix) gave a talk on the future of Nix surrounded by Guix hackers --- there is no rivalry between these two projects.

Great explanation.

Other than daemon implementation and design ideas that migrated from/to Nix/Guix, is there a way to write a package in Nix and use that derivation in Guix or vice-versa?

I ask thinking if it would be possible to somehow leverage the work on packages from on project to the other.

I think that derivations are at a level that is too low to be useful for interoperability. The format for derivations has not changed in Guix (yet?), but you wouldn't work on derivations directly most of the time. Most of the fun happens at a much higher level where an abstraction for packages and build systems exists.

The needs of the two projects have diverged over time and the daemon in Guix is slowly being rewritten in Scheme (this has been the subject of a GSoC project and most parts already exist on the Scheme side for other purposes). I would not count on continued compatibility, nor do I think it is particularly important simply because the contents of the derivations is different, so that there would be little difference between running both Nix and Guix on the same system and feeding Nix derivations to the Guix daemon (if that even works).

Nix uses it's own specific language. Guix uses Schema. Last time I checked Nix its interface was scattered into a bunch of tools. Nix is pretty neat though but not without weaknesses.

> Schema

You mean Scheme.

They've been working on unifying all those tools into one `nix` command à la git. I don't know how far they are in the process though.

I love Guix and GuixSD and would like to move to it as my main OS, but I dislike that they actively censor information on how to run a custom kernel and get set up on a machine where some drivers linux-libre removes are required. I understand that they don't want to distribute those stuff and that's fine, but not everybody can buy new hardware and especially any hardware easily. This is extremism for me (banning official information, not the offending drivers), it's distasteful and discourages me.

This is not censorship. We just don't want the #guix IRC channel or the project's mailing lists to recommend ways to use proprietary software. People are welcome to use non-project channels to discuss proprietary software.

So you have scatter information about how to actually make guix useful to a large number of users who over 13 different platforms that people use and hope users can use google search to reassemble said info.

This is inefficient and poorly considered. When my family got their first modern computer in my teens it ran windows. When we bought a better one so I could explore computer animation it ran windows. My first computer I paid for dual booted linux/windows. My computers now exclusively run linux.

I switched to free software because it was better ideologically but more importantly because I can presently use it to accomplish my goals.

Dual booting is surely inferior to just running free software from a software freedom standpoint but if I couldn't dual boot I might not have bothered at all.

Making nonfree sofware require an affirmative act beyond apt-install foo is a good step deleting all info from the official platform is unreasonable.

For more information, see the GNU Coding Standards:


In particular:

> A GNU program should not recommend, promote, or grant legitimacy to the use of any non-free program. Proprietary software is a social and ethical problem, and our aim is to put an end to that problem. We can’t stop some people from writing proprietary programs, or stop other people from using them, but we can and should refuse to advertise them to new potential customers, or to give the public the idea that their existence is ethical.

Excluding material isn't censorship---GNU stands by its principles. You wouldn't expect a vegan organization to advertise means of obtaining meat, for example.

I'd like to add that using proprietary software is not an act that deserves condemnation, it's not a moral failing or something like that. The GNU project opposes proprietary software as it is considered a social and ethical problem. Although I advise against it, you are free to use proprietary software for whatever reason (including possibly ethical or financial reasons) --- there are no mechanisms in place to prevent you from doing that in Guix (and the fact that Linux libre cannot load certain user-supplied firmware is a bug).

As a project, however, we do not recommend the use of proprietary software and don't provide a platform for advice on how to replace free parts of Guix with non-free software.

The use of proprietary software becomes an ethical problem when network effects are in place. Otherwise, it is the mechanisms of proprietary software itself that we object to, for example the barriers it poses to helping friends or neighbours and the way it gives developers control over the users.

> (...) deleting all info from the official platform is unreasonable.

There's many linux distributions and packaging systems where you can easily download proprietary drivers. It's nice that there exists at least one with a firm commitment to free software.

Notice that you can still install proprietary software on top of Guix; they just prefer not to promote it via the official communication channels. That's perfectly reasonable.

It's not "software" in that it's not something I choose to use. It's firmware, which is code that I have to use.

Also, even if you do not agree with the above statement, the kernel is unique enough to be granted an exception. If I can't get say sublime text or some proprietary decoder from the repos, that's a tiny annoyance; but if my screen gets funny colours or if I cannot connect to the wireless, that makes it unusable for me. And at that point you're effectively barring me from using free software (but with the exception of a couple blobs that I can totally live with given the status quo), not helping me adopt it. Yes Debian is not as cool (I really like Guix and GuixSD), but at least they are not impeding my day-to-day needs because of extremist morals.

When I asked on the official mailing list for help and was told kindly to f off, that makes me sour enough to say meh, I can use a relatively less interesting distro if it has a better, unconditionally helpful community.

Edit: also it's totally censorship to ban people from saying things they do know and could say.

Let's say I want to have the last five versions of my application installed as a mortal user, for testing purposes.

Let's say that my application's build system pulls in a big GUI toolkit binary because reasons.

Let's say I don't want to create "official" packages for it, just something quick and dirty that will get me these versions installed.

Can I do this with GNU Guix?

With Nix you can, and Guix is a Nix reimplementation, so you can too.

In Nix, some details are still a bit clunky. Like pinning particular package versions. But Nix / Guix are, in my opinion, already more useful and robust that other distros.

For edge cases, I still use some ad hoc Dockers.

> last five versions

If the build method has not changed then all you need is five tarballs and use `guix build foo --with-source=foo-0.0.n.tar.gz`.

> build system pulls in a big GUI toolkit binary

This is less likely to work, but it depends on how the big binary is linked.

> just something quick and dirty

You can use "guix build foo --with-source=..." for quick and dirty things. For something slightly less quick and slightly less dirty you can define a local package expression using the Guix DSL, dump that in a file, and build it from there.

My examples are in Nix, because that's what I'm familiar with, but everything should apply to Guix too (with some translation).

> Let's say I want to have the last five versions of my application installed as a mortal user, for testing purposes.

Sure, you can use linkFarm to collect multiple variants:

      pkgs = import <nixpkgs>;
      repoUrl = "https://gitlab.com/teozkr/sbtix.git";
      versions = [
          rev = "v1.0";
          sha256 = "storehash1";
          rev = "v1.1";
          sha256 = "storehash2";
      programOfVersion = version: pkgs.callPackage (pkgs.fetchgit {
        inherit (version) rev sha256;
        url = repoUrl;
      }) {};
      allBins = map (version: {
        name = "sbtix-${version.rev}";
        path = "${programOfVersion version}/bin/sbtix";
      }) versions;
      binFarm = pkgs.linkFarm "sbtix-binfarm" allBins;
      pkgs.linkFarm "sbtix-farm" [ {
        name = "bin";
        path = binFarm;
      } ];
That said... the Nix way would have been to just build the version you care about, when you care about it, without installing it globally. To do that you could just run `nix build` in your project directory, and then run `result/bin/my-program`.

> Let's say that my application's build system pulls in a big GUI toolkit binary because reasons.

Not sure which toolkit you're talking about, the the big ones (GTK, Qt, wxWidgets, etc) are already packaged for you.

> Let's say I don't want to create "official" packages for it, just something quick and dirty that will get me these versions installed.

This depends on what language you're using, but it's usually a matter of 1) defining your dependencies and 2) running your preferred build tool.

The usual recipe for a default.nix looks like this:

    { pkgs ? import <nixpkgs> {} }:
    pkgs.stdenv {
      name = "my-program";
      src = ./.;
      buildInputs = [ pkgs.qt5 pkgs.pulseaudio ... ];
      configurePhase = "./configure --prefix $out";
      buildPhase = "make";
      installPhase = "make install";
Though most languages have helpers to avoid this boilerplate (and, usually, to help with things like caching across builds).

Haskell has buildStackProject[1], Node has yarn2nix[2], etc. stdenv will default to the Autotools workflow (./configure; make; make install) if you don't define the phases yourself.

[1]: https://nixos.org/nixpkgs/manual/#how-to-build-a-haskell-pro...

[2]: https://github.com/moretea/yarn2nix

> Can I do this with GNU Guix?

Yes ;)

> Bootloader definitions are available for many boards—Novena, A20 OLinuXino, BeagleBone, and even NES.

I'd love to see somebody try to run GuixSD on a NES.

By "NES" they actually mean "NES Classic Edition" which is just a fairly normal modern ARM board in a neat looking box.

very very happy to see the project lively and kicking :)

The big problem that Nix/NixOS has is failure to integrate well with graphics libraries (OpenGL drivers, etc).

Does Guix solve this problem?

I've never had trouble with graphics on NixOS. What integration failures do you see?

I have been using NixOS for a week now. I am curious, could you give more details? I haven't tried any games, but Plasma is accelerated.

Probably referring to the proprietary drivers, not the open ones that I assume were included in the distro.

But the proprietary drivers are too, just add

    services.xserver.videoDrivers = [ "nvidia" ];

    services.xserver.videoDrivers = [ "ati_unfree" ];
to the system configuration and do a sudo nixos-build switch to switch into the new system with NVIDIA drivers.

(NixOS is pretty fantastic in this respect, in the installation live environment I just added

     boot.supportedFilesystems = [ "zfs" ];
to the configuration and switched to the new configuration. I could then do a root on ZFS install without any extra effort.)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact