尝试 Guix:一位 Nix 用户的心得体会
Trying Guix: A Nixer's impressions

原始链接: https://tazj.in/blog/trying-guix

## Guix:一位Nix用户的第一印象 本文详细记录了一位经验丰富的Nix用户周末尝试Guix的经历。Guix是一个完全替代的生态系统,建立在相似的基础包管理原则之上。虽然两个系统都采用函数式方法,但作者发现两者在架构上存在显著差异。Nix允许灵活地混合软件包集合,而Guix则采用固定的、基于Scheme模块的命名空间层次结构,需要完全重建(“guix pull”)才能更新版本——这个过程被发现比Nix的更新要慢得多。 最初的一个主要障碍是Guix对软件自由的坚定立场,为了硬件支持,必须使用“nonguix”来包含专有固件。作者赞扬了Guix专注的社区和 vastly 改进的文档,但也指出Scheme知识是先决条件。 尽管未能实现一个完全可用的桌面环境,作者仍然觉得Guix引人入胜,特别是它对Lisp的使用和连贯的生态系统。他们强调Guix的初始化系统Shepherd,可能比systemd更好。最终,作者计划在Guix中复制他们的NixOS配置,并简化迭代过程,以确定Guix是否能提供比他们已建立的Nix工作流程更好的优势。

## Guix 与 Nix:一则黑客新闻讨论总结 一则黑客新闻帖子,讲述了一位用户使用 Guix 的体验,引发了对 Guix 和 Nix 这两个函数式包管理器的比较。Guix 具有一些优势,例如使用已知的良好语言(Scheme)以及可能更好的可重复性,但仍然存在挑战。 讨论的关键点包括 Guix 更新速度较慢(尽管取决于硬件,初始拉取需要较长时间)以及与 Nix 相比,社区/基础设施规模较小。与 FSF 的关联也存在争议,一些人认为这是一种缺点,因为它被认为缺乏灵活性。 Nix 的复杂性经常受到批评,尤其是它的语言,但其更广泛的采用、平台支持和商业支持已被承认。Flakes 是 Nix 的一项新功能,存在争议,人们担心其性能和破坏兼容性。 一些评论者建议进行潜在的改进,例如使用 LLM 辅助的包从 Nix 翻译到 Guix,以及简化 Nix 包的设计。最终,这两个系统都被认为是很有前景的,Guix 吸引了那些寻求更原则化、基于 Lisp 的方法的人,而 Nix 则受益于更大的生态系统和务实的开发。
相关文章

原文

Trying Guix: A Nixer's Impressions

People occasionally ask me how I think Guix compares to Nix. Let me set the stage: I've been using Nix for many years, have large projects using Nix, used to be very active in the Nix community, and even wrote multiple Nix language interpreters, so I'd say that I'm at least fairly comfortable with Nix.

I'm also one of those people who live in Emacs. I'm no stranger to Lisps (although my experience with Scheme is limited) and am very fond of them. It feels natural that people ask me about my views on Guix.

The thing is: I haven't actually ever used Guix, so I just don't know. But there's an easy way to find out: let's try it! So that's what I did this weekend.

Here are a few things I ran into and found noteworthy. My goal was to take my Unchartevice laptop with its strange Zhaoxin x86_64-compatible CPU and see if I could get all the way to my standard niri desktop. There's no overarching point here, just observations a user of one or the other system might find interesting.

Spoiler: I didn't manage, but I saw a lot of interesting stuff. Knowing myself, I'll probably keep trying when some free time shows up.

A quick note before we begin: Technically, Guix uses a fork of the Nix daemon for the low-level primitives of functional package management (the Nix Guix Store, derivations, substitutions, and all that stuff are basically the same). The projects forked a long time ago, and development has diverged significantly since then. The similarities end here, however: Guix is not "just" Nix with Scheme — it's a complete alternative ecosystem built in parallel on top of the same foundational infrastructure. A mental model of "Nix with Lisp syntax" will not work in practice when approaching Guix.

Anyway, here we go.

Skip this if you want to get straight into the technical stuff.

Guix is the GNU system, and as such takes software freedoms very seriously. Guix does not recommend and does not ship the proprietary blobs needed for most modern hardware. The FSF has a website that lists laptops that work without them, but it is very limited. The majority of Guix System users use something called nonguix that adds these blobs, giving you access to things such as wireless internet.

I don't want to make this post about the political side of software freedoms, but I had to use nonguix to get internet working on the machine, which had very immediate technical effects that bring me to:

we mix nixpkgs commits all the time, because we track unstable releases and occasionally need to pick software from an older stable commit.

Guix doesn't work like this, and I found it very confusing at first. That's not to say it's bad — it's just different:

[ guix-daemon ] <-> [ guix CLI + profile ] <- [ Guix user code ]

As in Nix, the Guix daemon converses with the CLI over an RPC interface. The difference is that the Guix CLI runs in a fixed profile that has all of the packages and modules from all channels baked in. In contrast to Nix, the Guix package/service set is not one big data structure, but a namespaced hierarchy of Scheme modules. The Guix CLI is a Scheme environment in which packages, services and so on are available for import in user code.

This means that to change the Guix version (i.e., commit in their monorepo, which is the implementation of the CLI and of the package set, as if NixOS/nix and NixOS/nixpkgs were one) you essentially rebuild Guix. In Guix land, this happens through a command called guix pull, which ultimately yields (as I understand it) a new guix binary with a hardcoded profile.

This has two effects that were noticeable to me:

  1. Switching between versions is always at least a two-step process: Rebuild Guix, then rebuild your config. You can't easily, as in Nix, just import a different Guix commit in your code.
  2. Running guix pull is slow, and this makes the initial bootstrapping experience very frustrating. It's super-easy to build a configuration from some Guix commit, then run the wrong command and cache-bust everything as the commit changed (which, due to nonguix, often leads to a full Linux kernel rebuild—something you do not want to do on a Zhaoxin KX-6640MA!).

There isn't a right-or-wrong here: Guix uses a different model from Nix. For me, Nix's feels more natural, but this might just be bias due to familiarity.

For what it's worth, Liam from the #guix IRC channel pointed me towards a method for handling Guix "pins" in a better way, but I haven't tried it out yet.

Another thing that seems architecturally different is profile-wide installs of packages. In Guix they seem to be preferred over the Nix approach of creating isolated environments for specific programs with helpers. The most noticeable one for me was Emacs: People usually install Emacs packages right into their system or user profile from which Emacs loads them, whereas Nix has emacs.withPackages that takes a list of packages and builds a full Emacs with these packages baked in.

I haven't figured out if there is an equivalent to Nix's emacs.withPackages. Maybe I didn't look at the right people's configs? If there isn't, this kind of design makes some experimentation harder than on Nix: It's seemingly more difficult to try out packages without affecting the global namespace.

ranted before (in Russian) about how much I dislike the current state of systemd, and there are much more detailed posts about why systemd, albeit being an improvement over what came before it, is not very good.

Guix instead uses Shepherd, an init system written in Scheme. I don't have much to say about it yet, but it seems fairly straightforward and has excellent documentation. Once I continue with my experiment, I'll take a look again.