Hacker News new | past | comments | ask | show | jobs | submit login
The guide to software development with Guix (guix.gnu.org)
196 points by pabs3 on June 8, 2023 | hide | past | favorite | 135 comments



I much prefer GNU Guile over Nix. Anyone else? I saw some progress being made towards making NixOS compatible with other programming languages.


I think with the introduction of Nickel [1], Nix packages would be rewritten in it over time, which may be a good thing (types) or a bad thing (another fragmentation after flakes) depending on your point of view.

On the other hand, Guile is not a DSL but a general purpose language or a Lisp (Scheme to be exact), so it's not actually a downside compared to a DSL in my view.

I myself am torn between these two. Nix community is larger and they have more packages. Guix, being a GNU project, obsessing over ""non-free"" sure won't help in its adoption. Even debian folks toned down their stance on this, why couldn't Guix do so too?

[1]: https://github.com/tweag/nickel


> Guix, being a GNU project, obsessing over nON-fReE

As a long time contributor to Guix I find that the "obsessing" is regularly done by others when talking about GNU. There's enough useful free software out there that needs packaging, and that's what I do. I don't need the extra headache of special snowflake licenses or custom restrictions.

For nonfree software that doesn't have a popular alternative I contribute to guix-science-nonfree. It's barely an inconvenience for users to expressly add another channel to their Guix installation.


When I used Guix, I needed nonfree for Firefox and the upstream Linux kernel. I also prefer to only use free software, and also like them not including proprietary software.

Needing a channel was a huge inconvenience as you would often pull your channels and stuff would break, as guix was updated but non-guix wasn't. Managing channel manifests was a pain. Firefox would often be months out of date as well.

Moved to NixOS, didn't enable allowUnfree, and had an actually up to date and simple to maintain system. Flakes solves the channels problems too. I had put a lot of effort into making Guix work, but it just had too many usabiltity issues, and the policy on firefox was a major one.


Counter anecodate: I use guix + the nonguix channel for firefox, linux, etc. and it has been smooth sailing for quite some time.


Guix comes with a service for using Nix packages[1], if that's what you want. It's very simple to setup, and would allow you to use Nix's Firefox package without any issue.

[1] https://guix.gnu.org/manual/en/html_node/Miscellaneous-Servi...


I've been using guix since 0.15.0 and haven't seen it as much of an issue. Sure, channels will sometimes be out of sync with the latest commit but that's to be expected given that you're likely not following a version cut but rather the latest commit. It's easy enough to bump the package locally (inherit, etc) or contribute an update which solves this for everyone.

Needing channels for non-free is a feature as the system will be pure by default and can make progress towards fully reproducible builds for all packages rather than having several blessed non-free blobs around that drain maintainance time.

For the record, I use linux-nonfree, amdgpu, iwlwifi, firefox, and steam.


I'm not sure how long ago you used Guix, but in my experience, modern day nonguix is very up to date with Firefox and upstream Linux. Combined with things like Guix shell, time machine, and pinning specific commits, I find things have not broken for me in ways that I couldn't easily resolve in a few minutes in a long time.


I've been using Guix for a bit over 2 months at this point and honestly the whole 'non-free' software thing has not been an issue in the slightest. Use the System Crafters installation iso [1] to get around driver issues on install, and then the only time I've ever had the system complain to me was it warning me one of my hardware components wouldn't work (which it did, since the System Crafters ISO uses the standard Linux kernel). Afterwards, just add nonguix (and I even added Nix as well, so I get the best of both worlds!) If a package isn't in Guix and I don't want to make a package definition, I simply pull it using Nix home-manager. May not be the best or 'proper' setup, but I find it works well enough. [2]

[1]: https://github.com/SystemCrafters/guix-installer/releases

[2]: https://g.stationery.lol/ryan77627/guix-dotfiles


For installation and setting up something as basic as drivers, we should follow a non-official guide?


Yes if your only connection is wi-fi with drivers that require nonfree firmware, which is missing from the official ISO. You're supposed to discuss nonfree software in some non-official place too. That's what been stopping me as well; the system seems technically superior to Nix and not nearly as chaotic, but hardcore FOSS idealism makes it impractical sometimes.


I will admit, I was hesitant as well, but so far it's been fine. The #guix community on libera.chat is very active and has been nothing short of amazing in helping me understand the ins and outs of Guix. For any non-free software I use, #nonguix in libera.chat exists. It's less active but still pretty active (plus I pop in occasionally).


No, feel free to use the official guide, it's still very, very, very helpful. Yes, you do need to use an unofficial image, but that's just if you have hardware that requires non-free drivers (or blobbed drivers, Guix uses Linux-Libre by default).

Not the best of circumstances, I know, but it works (plus if you really wanted to, they give the derivation details in the release notes so you could just spin up a Guix VM which runs fine with the default image and generate the image yourself).


For the record, Nix doesn't let you install unfree packages by default either. You have to flip a flag to allow it and you can also supply a predicate to conditionally approve unfree packages (https://nixos.org/manual/nixpkgs/stable/#sec-allow-unfree).


> I myself am torn between these two.

As a regular Nix user and occasional Guix dabbler, I think you really can't go wrong either way. I feel that Guix often gets short shrift here on HN, but at the end of the day it's a really thoughtfully designed project with a capable community and great documentation.


I find Nix to be very close to the perfect DSL for what it does, and I like it quite a lot. But then I never bothered to look at Guix closely -- is its DSL at least lazy? Are there any honest comparisons wrt verbosity and awkwardness of Nix and Guix for stuff both are supposed to be good at?

No idea what "making NixOS compatible with other programming languages" is supposed to mean. On the face of it the phrase is, well, baffling. Would you care to elaborate?


> its DSL at least lazy

This keeps getting asked and it's baffling to me. Any programming language can delay evaluation by wrapping values in thunks where that makes sense, so it seems odd to me to give so much importance to whether values are evaluated strictly or delayed by default.

Guix package definitions declare other package values as inputs, and evaluation of these inputs is in fact delayed.

Verbosity: in Guix we don't generally run shell snippets as part of a build; the build phases are compiled into a Guile builder script, so in the absence of helpful abstractions build phases do not generally have the conciseness of shell scripts. On the other hand abstractions are easily fashioned, so some things are more concise and clearer than the shell equivalent.


> > its DSL at least lazy

> This keeps getting asked and it's baffling to me. Any programming language can delay evaluation by wrapping values in thunks where that makes sense, so it seems odd to me to give so much importance to whether values are evaluated strictly or delayed by default.

At least in Haskell laziness increases composability.

I can't think of any examples in Nix, but maybe it's the same reason?


One use case for lazy evaluation in NixOS is that you can reference other parts of the system configuration, possibly even defined in other modules, as long as you don't produce cyclic references. For example, I use stuff like the following often to avoid accidentally specifying a username that does not exist:

  { config, ... }:
  {
   systemd.services.foobar = {
    enable = true;
    serviceConfig.User = config.users.users.foobar.name;
    # etc...
   };
  }
Another use case is being able to keep everything as plain values. For example, I can run `import <nixpkgs> { }` without evaluating all of `nixpkgs`. You can accomplish that in a language with eager evaluation by wrapping values in functions but I prefer the everything-is-a-value way.

Of course, this is just a matter of preference. Like most Guix vs. Nix aspects, as far as I can tell.


The "service" mechanism in Guix System is designed in part as a reaction against those the NixOS module design you're describing: I think the ambient authority, free-style extension mechanism of NixOS modules makes it hard to reason about it (any module can change the config of any other module), and it makes it easy to shoot oneself in the foot (with infinite recursion in particular, as you write).

In Guix System, services extend one another, forming a directed acyclic graph of extensions. When a service extends another service, that connection is explicitly declared, there's no surprise.

To see what it means in practice, check out the Explorer: https://notabug.org/civodul/guix-explorer


Nix bombs out when it runs into a cyclic reference, so at least infinite recursion doesn't hang without any output. Likewise, it also rejects multiple definitions for a value (though to be fair some values like attribute sets are mergeable and it can be hard to wrap one's head around that).

The service model in Guix looks pretty neat! I've long been thinking it would be nice to have a configuration system for NixOS that uses isolated components with a defined (type-safe) interface. The current modules are kind of that, except it all gets squashed down into a single nested attribute set, so it's not really isolated and (understandably) can be confusing. How does Guix System handle multiple services competing for the same global resource (port allocation, file in /etc, ...)?


There's nothing to prevent multiple services from using the same port at this stage. For files in /etc, the "etc" service should detect that the same file appears more than once and error out--that is, it won't instantiate a "broken" system.

There are other things that are detected statically and prevent you from instantiating a broken system: missing modules in the initrd, invalid file system label/UUID, references to non-existent Shepherd services, etc. All this is possible because there are well-defined data types and semantics for the different components of the system.


Fair enough, NixOS doesn't completely solve this either (other than the aforementioned possibility to reference other parts of the system config and some integrity checks). I was just wondering if that's an area where more static checks are possible.

That sounds pretty good though, thanks! Maybe I'll try out Guix System some day.


> Any programming language can delay evaluation by wrapping values in thunks where that makes sense

Indeed. I was simply asking whether the macros used for programming Guix are lazy, how is that baffling?


It's baffling because the question is too vague to produce a meaningful answer. What does it mean for macros in Guix to be lazy? The expansion of some macros may be (and is) lazy. For some things lazy evaluation is sensible (e.g. for declaring dependencies because you don't necessarily want to go evaluate the whole graph whenever you evaluate a single package value), for others it is not.


One thing that's often overlooked with Nix (the language) is that it does not let you define new data types. For example, there's no "package" type in Nix and Nixpkgs; instead there are only functions that are passed "attribute sets" (key/value dictionaries).

That Nix can't tell what's a package and what's not is a hindrance for its user interface (e.g., it's hard to look up packages by name/version or to iterate over them) and for packagers (e.g., easy to end up with package definitions that don't follow the informal "schema").


This presentation I think was a fair attempt to compare, or at least to look at Guix from a Nix perspective

https://youtu.be/bDGzCXr6VYU


Guix uses Guile, which is a general purpose scheme/lisp dialect, allowing for lazy evaluation


I know quite well what Guile and Scheme are; I was asking about the specific DSL/library/whatever combo that Guix is programmed in. The code snippets on the page which this thread is about, for example, mostly use macros that seem to mimic their Nix equivalents very closely but are marginally more verbose. I would very much like to see a compelling example where the fact that Guile has macros makes a practical difference.

(Note that Nix's laziness is not an unalloyed good either, for example it is notoriously difficult to debug. But let's limit ourselves to pure expressiveness for now)


Well I mean look at the docs. To each their own but I find Guile much more palatable than Nix. Moreover, I would rather spend time learning Guile than an obscure language like Nix. But for you Nix is a perfect DSL so i think we would probably be bashing our heads against the wall debating which is better.

As regards macros, Guile allows you to write your own macros in a pretty straight forward way that is just not the case in Nix


I'm not trying to "debate" anything here.

I do note that those Guix people that are feeling competitive towards Nix for whatever reason tend to over-rely on two arguments that just do not work too well when examined closely.

The first is "Nix is obscure the way Guile is not". I would argue both are equally obscure and neither is obscure enough for its quality or UX to suffer for it. And does expertise in Guile (base Scheme is trivial) carry over anywhere interesting?

The second is "Macros!", where the implied idea is that unrestricted syntactic extensibility is Good. Well, I like Lisp (more partial to CL then Scheme, but who cares at this resolution), and I find unrestricted syntactic extensibility to be more of a hazard than a benefit; plus the expressivity of a non-strict FP language really gets you close enough for practical purposes.


> does expertise in Guile (base Scheme is trivial) carry over anywhere interesting?

If you ever want to embed a dynamic language in a native code program for configuring/scripting the latter, Guile is a great choice.


It is, but there already are other choices that are not worse and that are more established


What, for example? The only other one I can think of is Lua and IMO it’s quite debatable whether that is more established than Guile.


please compare:

https://archlinux.org/packages/extra/x86_64/lua/#pkgreqs

https://archlinux.org/packages/core/x86_64/guile/#pkgreqs

(lua at least is under-counted as there is luajit, lua51, and various packages which embed their own version, e.g. pandoc)


It is at least used outside of the GNU Project...


Besider Guix, Guile is also the default extension language for the GNU project. Moreover by learning Guile you learn a lisp which some people find quite enlightening. What do you gain from learning Nix, asside from Nix?

Moreover, "macros are good" in the sense that they are powerful and grant the user freedom to construct software in ways that are just not possible with languages that try to herd their users into a specific mode of behavioir. It is the old freedom and responsibility problem. Again, I believe it is a matter of choice and personal preference


Oh boy.

> Guile is also the default extension language for the GNU project.

AFAIK Guix is the only project that uses Guile and has any actual users (I'm not counting Shepherd because outside GuixSD it is nothing). Guile is like 30 years old, and has been envisioned as "the default extension language for the GNU project" all that time (I was an active contributor for a while, so I should know). Guile is not even used by Emacs; Guile extensibility support in GDB is not even commonly built by distros. Guile is a nice and very competent Scheme implementation and I'd love for it to be useful outside Guix, but that's just not the case, and repeating that slogan won't change it. Seriously, just stop.

> It is the old freedom and responsibility problem

No, it is not. Software development is a social and technical field, not a branch of philosophy.


> AFAIK Guix is the only project that uses Guile and has any actual users

TeXmacs (https://texmacs.org) uses Guile, Gimp uses a Scheme, and learning Guile for Guix should be transferable with little changes to other Schemes.


Oh boy, you didn't even answer my question about Nix. I guess you can't in a way that doesn't concede to my point - guile is definitely not obscure in the sense that nix is.

For what its worth, here is at least one recent funded project that is using Guile:

https://spritely.institute/goblins/

You also seem to think that I am some kind of Guix/Guile evangelist. No (I actually also prefer CL). I just happen to think that Guix is a better solution than Nix and that it uses a much better language.

> No, it is not. Software development is a social and technical field, not a branch of philosophy.

And I guess you get to say what's good and bad in field? Lol


> you didn't even answer my question about Nix.

Your question was basically "is this DSL generally useful outside the domain it's been designed for?", so I thought it was rhetorical. That said, the domain of building, configuring and packaging software is not exactly tiny and is only getting bigger as time goes on (which is more bad than good in itself, but beside the point)!

How useful is the DSL implemented by Guix outside Guix itself? What's the comparative mental footprint of that vs. base Guile? Things get interesting when you think them through honestly and avoid stale slogans.


DSL implemented by Guix? Whatever do you mean?

Anyway, most people that I've come across who've used both nix and guix say that the learning curve for the latter is much less. HOWEVER, they usually stayed with nix because it had easier access to non-gnu stuff


> DSL implemented by Guix? Whatever do you mean?

From what I've seen (which matches my expectations going in), Guix relies on macros heavily enough to be considered a DSL on top of Guile (as opposed to "library" or "framework"). I could be wrong, of course.


Having macros does not equal having a DSL. In fact for me a big benefit of Guix is precisely that it doesn't use a DSL, but uses a well established and maleable language like Guile (Scheme)


> Having macros does not equal having a DSL.

Any set of non-trivial non-standard macros is a DSL, by definition. You have to know what a macro does and what it is for in order to even understand which of its similar-looking keyword or positional arguments are evaluated and which are not, how they relate to each other, etc, etc. I really don't see what you are arguing about here, or to what end.


> Any set of non-trivial non-standard macros is a DSL, by definition.

thats not entirely correct but even with that definition you should think about the non-standard part. guix uses standard guile syntax and has the whole guile language available to it.

anyway i think you are trying way too hard to equate nix and guile in a way thats simply doesnt click with me. maybe you invested too much time learning nix to concede that there is something better and simpler out there


> guix uses standard guile syntax and has the whole guile language available to it.

I feel I'm not getting through here. Let me try again: Guile is base Scheme plus some SRFIs plus some more extensions. None of this is useful outside the Guix bubble, because it is not really used for anything outside that bubble. I suppose pointing at a hundred Texmacs users who picked it up after being exposed to Guix would prove me wrong, but good luck with that.

> maybe you invested too much time learning nix

Maybe armchair psychoanalysis is extremely bad form. Note that I'm not trying to argue against Guix (or Guile, or GNU, or whatever) -- for all I know Guix is just great, and I know Guile is great (shall I rephrase and repeat this disclaimer again until it "clicks"?). I just tend to be triggered by idiotic sloganeering argumentation, especially when it is repeatedly reflexively employed as if it can substitute for a honest technical comparison.


> Guile is base Scheme plus some SRFIs plus some more extensions. None of this is useful outside the Guix bubble, because it is not really used for anything outside that bubble.

"idiotic sloganeering argumentation"?

> honest technical comparison

let me spell it out for you in another way

nix is developed in cpp (which itself is a huge collection of dsls) and you use its own (poorly documented) dsl to interact with it

guix is developed in guile and you use guile to interact with it

this alone implies that you get far more from just learning guile than nix dsl if all you want to do is package management

as for a one to one technical comparison, it is just a google search away: https://gist.github.com/abcdw/e54807b0a25e61fe2cf1bf8991410f...

>I suppose pointing at a hundred Texmacs users who picked it up after being exposed to Guix would prove me wrong, but good luck with that.

you keep sloganeering that guile is useless outside of guix. i find it pretty funny how willing you are to twist the picture of reality in order for it to fit your world view. i already pointed you to another significant project that uses guile. here is the part in their documentaion spelling out their choice for guile: https://spritely.institute/static/papers/spritely-core.html#...

as for texmacs, i dont know where you are pulling your numbers from, but i for one used texmacs for writing papers before even considering taking on software development professionally. so please don't be triggered if i dont take your claim at face value


And let me make some further general observations here, while I'm unfortunately procrastinating.

People use software to solve their problems. The way you "sell" (in whatever sense) software to people is by showing them which of their problems it solves (they don't even have to be explicitly aware they have those problems in the first place, BTW) and how.

Nix(OS) is adopted first and foremost because it clearly solves some pressing problems. It allows you to have many development environments that don't stomp on each other, without managing a zoo of containers or VMs. It allows you to specify the operating system (or even just the user environment) you use, over as many machines as you need, deterministically and while ensuring that once you solve a problem it stays solved.

Those are real pain points, and since Nix solves them it would be used by people regardless of those people feel about Nix-the-language, because language appreciation is not the main reason people use it -- pain is.

Some goes for Guix, obviously.

So if your goal (whatever your motivation may be) is to explain to a Nix user how Guix is better, you need to point out something that is relevant to the person you are "selling" to and is fundamentally painful with Nix and painless with Guix. And, well, reaching first thing for "Guile is the official extension language of the GNU Project" does not do your marketing effort any favors.


> So if your goal (whatever your motivation may be) is to explain to a Nix user how Guix is better

I never said that that is my goal


> another significant project that uses guile.

That looks like a typical academic project that is overwhelmingly likely to die as soon as the grants run out, what am I missing? Where are the users?

> nix is developed in cpp

Who cares?

> its own (poorly documented) dsl to interact with it

Nix documentation is not by any means ideal and is kind of scattered, but calling it "poor" is a blatant misrepresentation.

> guix is developed in guile and you use guile to interact with it > this alone implies that you get far more from just learning guile than nix dsl > if all you want to do is package management

Argument by repetition, wonderful.

> as for a one to one technical comparison, it is just a google search away

That is... not good. And when a commenter pointed out its biases and misleading generalizations, the author invited them to go listen to a stream, lol, nope.

> you keep sloganeering that guile is useless outside of guix.

That's because it is, no need to get so defensive about it. It does not detract from its technical qualities! In any case, the goalpost got moved way far from the original "Guile iS tHe OfFiCiAl eXtEnSiOn LaNgUaGe Of ThE gNu PrOjEcT", wouldn't you say?

> forgive me if i dont take your claim at face value

"Guile is for all practical purposes useless outside the Guix ecosystem" is my null hypothesis here and so far I stand by it. "Proving" that would be proving a negative, so I don't intend to even attempt that. It should, however, be fairly easy to disprove if you have data. Show us how learning Guile (or any Lisp that is not Elisp really -- sad!) is likely to be worthwhile for a "normal person" apart from using it for Guix.


if you know nix DSL but dont know cpp (whatever it means to know cpp) then the whole nix internals are just a black box to you. this is simply not the case with guix. if you cant see the benefit of guix/guile relationship here then there is not much more i can say to you

anyway as i said at the start this whole thing is just heads banging against a wall. i have no problems with you holding your views. it just happens that i disagree with them. if you expect of me to promote the virtues of lisp to you then im sorry but thats not gonna happen. you can do your own discovery. if you dont know then you dont know :)


> the whole nix internals are just a black box to you.

Yes, and just as well. Modern software is a barely-holding-together tower of abstractions as it is. Do you find yourself looking at the C source of Guile's runtime often? Or Glibc? The Linux kernel? Intel microcode? Aren't you glad you don't have to?

(Nixpkgs, on the other hand, is very accessible and many parts of it make for great reading)

> if you expect of me to promote the virtues of lisp to you then im sorry but thats not gonna happen.

No, I hope (in vain, looks like) that you'll start making some sense and stop using and then desperately defending stupid arguments.


lol so now you think that looking at nix internals is like looking at intel microde. my hat goes off to you :)

regardless of who is right, the fervent opinions and bless-your-hearts in this thread tell me that I'm better off using neither. Purity tests are fucking dumb, escalating goalposts are fucking dumb, worrying about how others compute is fucking dumb. We're all nerds here, there's no need for this level of emotional investment into other people's opinions..


You're absolutely right, but if that makes you not try something you might be missing out. For example, Rust is probably my favorite programming language (definitely my favorite native-code-producing one) even though I find some of the community extremely off-putting.


> What do you gain from learning Nix, asside from Nix?

Nix is a small and approachable lazy pure-functional language. You can learn a fair bit of functional programming by reading nixpkgs, which is frequently recommended even if you never use it in the real world.

> by learning Guile you learn a lisp which some people find quite enlightening.

By learning nix you learn a FP language which some people find quite enlightening.

Personally I can't find any software which I would want to contribute to or extend which uses guile (except GDB which can also be extended with python), so the "you ain't gonna need it" argument holds for guix too.

It's just such an odd argument for a relatively minor difference between the two ecosystems.


What you say would be the case if Nix uses Haskell or Guix uses some obscure purpouse made lisp


again, you said

> by learning Guile you learn a lisp which some people find quite enlightening

so learning a lisp is enlightening, but learning a FP language is not


FP is a paradigm. lisp is a language. you can use lisp to learn FP

if i wanted to learn pure FP i would probably pick many things over Nix


> if i wanted to learn pure FP i would probably pick many things over Nix

of course, but that wasn't the question:

> What do you gain from learning Nix, asside from Nix?


but if you wanted to learn lisp/scheme Guile is a very good choice whereas if you wanted to learn FP Nix is a pretty crappy choice


> Moreover by learning Guile you learn a lisp which some people find quite enlightening. What do you gain from learning Nix, asside from Nix?

This thread is baffling. cmm is asking a fairly simple question. He's not trying to make a point. If people don't have the answer, they need not respond! There are so many responses to him - none answering his question.


lol everyone seems to be baffled in this thread. i am just adressing his claim that guile and nix are equally obscure. which to me is just plain silly


If you're into Lisp/Scheme, it sounds silly.

If you're part of the 99% who know little of Lisp languages, he is correct. There's not much of a difference between 0.001% and 0.01%, when you're working in numbers like 20+%.


And even more than that: I think Guile specifically would long have been abandoned and forgotten about if not for Guix.


While Guix is the Guileverse's biggest and most successful project, a lot of the compiler/VM work that happens in Guile happens pretty independently because Andy Wingo just likes to hack on Guile. Guile would still be here, but the community would be smaller.


what are these numbers? i think any person with a cs education would at least recognise lisp syntax


> i think any person with a cs education would at least recognise lisp syntax

The discussion wasn't on Lisp, but Guile. They may recognize Lisp syntax, but the majority will not have heard of Guile (let alone Scheme).

And you are referring to recognizing Lisp syntax, which is not what I was referring to when I said "know little of Lisp languages". Sure - most know it exists and has a lot of parentheses.

BTW, many if not most programmers don't have a CS education. And many who do don't encounter Lisp in their curriculum. I just checked my undergrad's required courses - the PL course has Java, SML, Prolog and Python - no Lisp. Anecdotally, in all the teams I've worked in for my career, there was only one team where people had an idea of Lisp. In the other teams, they didn't even know that it's the language with a lot of parentheses (as in they'd look at Lisp code and have no idea which language it was).


it would make more sense to write "majority will not have heard of Scheme (let alone Guile)"

still who knows Nix?


Does it matter?


yes


I'm in love with Scheme, so would much rather use Guile/Guix for this than learn Nix's DSL that's not even lispy and that's not used anywhere else.


These days those aren't the only options; you can also use Nickel: https://github.com/nickel-lang/nickel-nix

Which isn't fully baked, no, but here's hoping.


Well. One is a language that has metasyntactic abilities and a decent standard library. One is not. Defining a package in guix is a lot nicer than in nix


Opposite for me. Nix syntax is much more pleasant to use and while Nix error messages are by no means perfect, still more fun than digging through multiple layers of Scheme.

Does Guix have anything similar to Nix flakes yet?


I believe the use of Guix channels shown in the article is comparable to Flakes.


From what I understand, channels can be used to extend Guix, but don't quite work like Flakes, more like the old Nix channels. The thing that makes Flakes special is that they allow you to treat Git repositories like software packages. No more need for a distribution to package the software, you can just drop a 'flake.nix' file into the Git repository and that makes it behave like a package that users can install and other Flakes can depend on. I am really fond of the ability to just run software straight from Git, e.g.:

   nix run github:ggerganov/llama.cpp
Makes it really easy to switch versions, fork, patch or otherwise customize things.


The blog post in this submission makes the same point: a git repo can be a channel, you just need to add a file for it.


I personally prefer Nix greatly it's just JSON with functions basically. I just find Guile expressions totally unreadable with the brackets everywhere.


Genuine question, not trying to create or sustain a debate: are there more brackets in scheme than in json? I don't use json much, but the example I find in the "Syntax" section of the Wikipedia article on json [0], looks almost identical to how I'd structure the same data in Scheme, though with more quotation marks [1]. Is this just a bad example?

[0] - https://en.wikipedia.org/wiki/JSON#Syntax

[1] - Edit: more quotation marks, commas, and colons


It's about specialization. In JSON brackets have dedicated meaning. In scheme it's () galore. And () doesn't give me any meaning of what's actually there. Not that JSON or the Nix language is perfect, or even good, but this point makes it a lot better then a Lisp for me.

Essentially quickly scanning over lisp code doesn't give me any inclination about the structure at all, which I think is very important. I admit I haven't written a ton of lisp so maybe that's the problem.


I read you. I think Guile's native syntax for keywords, though more explicit, probably makes it worse. I imagine this would be clearer for a non-Lisper? Valid CL, but not Guile without a configuration change.

  '(:firstName "John"
    :lastName "Smith"
    :isAlive t
    :age 27
    :address (:streetAdddress "21 2nd Street"
              :city "New York"
              :state "NY"
              :postalCode "10021-3100")
    :phoneNumbers ((:type "home"
                    :number "212 555-1234")
                   (:type "office"
                    :number "646 555 4597"))
    :children ("Catherine"
               "Thomas"
               "Trevor")
    :spouse nil)
...or, indented more like Wiki's JSON example:

  '(
    :firstName "John"
    :lastName "Smith"
    :isAlive t
    :age 27
    :address (
      :streetAdddress "21 2nd Street"
      :city "New York"
      :state "NY"
      :postalCode "10021-3100"
    )
    :phoneNumbers (
      (
       :type "home"
       :number "212 555-1234"
      )
      (
       :type "office"
       :number "646 555 4597"
      )
    )  
    :children (
      "Catherine"
      "Thomas"
      "Trevor"
    )
    :spouse nil
   )


The core issue that you can't escape is that Scheme creates a lot of ambiguity between data and code, since both use the same syntax. There is nothing wrong with using plain s-expressions for data, quite the opposite, I find them quite nice to look at, no need for keywords here:

    (person
     (firstName "John")
     (lastName "Smith")
     (isAlive t)
     (age 27)
     (address
      (streetAdddress "21 2nd Street")
      (city "New York")
      (state "NY")
      (postalCode "10021-3100")
      )
    )
But that's not something you can put in a Scheme file directly, you have to quote it and then you have to use quasiquotes, macros or other hacks to get parts of that data structure executable. It's also not even the proper way to do a name/value pairs in Scheme, which would be the alist of the form ((name . value) ...).

In Nix you do not have any of those ambiguities {} is a set, [] is a list, 5+5 is an expression, a = 5; is an assignment. And you can freely mix them without all that quoting, so it's { a = 5 + 5; }, not `((a . ,(+ 5 5))) or (list (cons 'a (+ 5 5)))


The difference is that name/value pairs have a dedicated syntax in JSON and Nix, in Scheme everything is (), doesn't matter if it's a function call, list, assignment, macro or whatever. Makes it very hard to understand what is going on at first glance. Worse yet, the normal Scheme syntax is so ugly that people constantly write macros to hide it. Take this package definition in Guix:

  (package
    ...
    (build-system gnu-build-system)
    (arguments '(#:configure-flags '("--enable-silent-rules")))
    (inputs (list gawk))
Looks like a list with name/value pairs, but it's not, that's just the (package)-macro making that thing behave that way. And it's all quite arbitrary, '#:configure-flags' there is a name/value list too, but constructed completely differently. And the next line with (inputs) constructs a list with (list) instead of with a ' quote, as otherwise the list would contain the symbol 'gawk' instead of the value.

Scheme is basically: "Here is the a bunch of Lego, go build yourself a programming language". Other language have syntax that forces at least a minimum of consistency.


How do Guix and Nix userbases and contributor resources compare?

I like Guix as a standalone package manager much much more. It has first-class support for single-file environment config, and it's in lisp! But a package manager system ultimately comes down to resources poured into maintaining and supporting packages, it's a bootstrap problem. It's clear that NixOS has substantial support. What about Guix?


Nixpkgs is enormously larger.

I like Guix better in principle as well, but it should be clear that its principled stance on what software can be packaged means it's a nonstarter for many people.


Well, with more than 23K packages, it's fair to say that Guix can satisfy the needs of many people, too. A lot of programming languages are pretty well represented!


Not just 23K packages --- that's just what is in the main Guix channel. Nix has a whole bunch of packages that are created automatically, on the fly, such as most R packages. The Guix equivalent would be the humongous guix-cran channel, which provides automatically generated R packages.

So I think comparing the size of package collections is less interesting than checking whether your packages are included. Personally, I would have a very hard time with Nix because I need the quality control in Guix that gets me packages that have been built completely from source without depending on opaque upstream blobs (e.g. bundled jars, minified JavaScript, etc). Because of that I wouldn't be able to use Nix productively for bioinformatics, statistics, and things like pytorch in the same way as I use Guix.


Good point. It's telling that many Nix vs. Guix discussions focus on three topics: DSL, popularity, and non-free packages. Few people talk about package quality control even though it's rather crucial for day-to-day use.

A while back I wrote about what it means to package something like PyTorch with the kind of quality control Guix has: https://hpc.guix.info/blog/2021/09/whats-in-a-package/


I'm not at all living in the Guix world, so please forgive my ignorance here. (I actually kind of gave up on the dumpster fire that are native binaries and happily live in my JVM bubble these days) But based on your article, I think you can take things a bit further to their natural conclusion

The last step is dealing with CMake. You can actually produce correct/reproduceabile crossplatform, crossarchicture builds WITH diamond dependencies and all that jazz if you integrate with the Hunter dependency manager. I think it's the only way you can get to a point where you don't end up with redundant dependencies at different version numbers

I wrote this high-level article about it years ago: https://kxygk.github.io/hunterintro.html

I mean, I actually frankly don't see a clear line between CMake "build orchestration" tools and dependency managers like Guix. Ideally Guix would just take over the function of CMake entirely - but it's missing crucial pieces. I think fundamentally you have 90% of the pieces there. You've already specified the whole dependency tree and dealt with linking/paths. The last 10% is extracting what CMake calls the "toolchain file" - ie. the specification for how you what you build done (target OS, architecture, compiler, linker and compilation/linking flags).

Ultimately it feels like with a bit more abstraction GUIX could be a truly crossplatform build/package manager. One could imagine for instance passing it a -debug flag and having it propagate to all dependencies and build your whole world with symbols. Debugging would become "full stack". Or passing in another flag and building one huge static binary with all dependencies and then doing PGO on it. Building crossplatform would become a breeze. Introducing a new architecture would be simply a matter of specifying a new toolchain file

I spent way too much time on reproduceabile CMake builds. We had our library reprucibly building for a huge amount of targets from Windows to iPhone 9 with a dozen dependencies that had diamond dependencies and it all worked beautifully. But I was kind of horrified that almost nobody in the C/C++ world really care about this. The tools were there and no one was using them (granted Hunter, while easy to use, has a bit of learning curve)

Ultimately I think it's something that needs to be solved at a "higher level" of the package manager bc cross language monsters like PyTorch are the norm now a days


This. NixOS was very usable for me back when Nixpkgs was the same size as Guix's package collection is now.

Additionally, Guix's package collection growth currently looks exponential, year over year. The package collection size gap, assuming it sticks around at all, is only going to shrink (relative to the total size of either collection) and matter less and less over time.


Guix can be extended with channels, and so there are channels like nonguix (for nonfree software) or guix-science (for software that's too messy to include in Guix proper) that go beyond what quality control keeps out of Guix proper.


> its principled stance on what software can be packaged means it's a nonstarter for many people

Including me. Guix actively makes it harder to install nonfree software, and that's against my personal principles, in addition to making my life harder on a practical level.


Guix actually makes an effort to make extensions of the maintained Guix channel as easy as the design choices allow. You can extend Guix in various ways: adding whatever channels you find or maintain yourself, extending it by setting GUIX_PACKAGE_PATH to a bunch of files, or by telling Guile to load some modules from somewhere else with "-L /where/your/files/are".

Guix doesn't care what software you install with it. It doesn't demand that you subscribe to any philosophy. The project just chooses to only package and distribute free software in the main channel. There are projects that have dedicated themselves to extending Guix with non-free or ... weird software. Guix will never go out of its way to make using those channels harder.


But if you dare to use the non-free channel, you get shouted at if you try to ask for any form of assistance, even for problems entirely unrelated to it. Speaking from experience.


wat? I'm using channels providing nonfree software. Even "worse", I contribute to those channels.

These channels are not for #guix, because the discussion there is meant for the base channel provided and maintained by the Guix project; but on #nonguix, or #guix-hpc (for e.g. guix-science, guix-science-nonfree, etc) you get to discuss these channels all you want and get help.


Using nonfree packages in Nix feels like buying wine at the grocery store: small, infrequent, ephemeral hassles. Using nonfree packages in Guix feels like having to go to a small, obscure package store across town.


I very much prefer the Guix community because based on my personal experience, it is more friendly and helpful than the Nix community. The main help ressources are the help-guix mailing-list and the IRC channel.


Guix can certainly beat Nix on documentation, with a lot following from that.


How would one use a modern IDE in this environment especially when you have multiple projects with different dependencies open at the same time? Would one need to install the IDE as a dependency of a project? Would all the IDEs have different settings?


You may use direnv which supports many IDEs, e.g. VSCode and Emacs. Here's a tutorial for Emacs: https://rednosehacker.com/combo-guix-shell-emacs-envrc-el


I use Emacs installed for my user account (so not as a dependency of any project), and install an integration that works with 'guix shell' for per-project software configurations. Emacs' project.el extension allows me to switch between many projects easily.


Curious what integration you're using? I'm using direnv with envrc but I'm interested to see of any good alternatives.


I use buffer-env. Some things that I don't love about it but it does the job and it understands guix.scm/manifest.scm files natively so I don't have to put them in an .envrc file or anything.


That depends on what you want to containerize (which I assume you are after? If you don't containerize it works just like any other distro--it will be transparent to the IDE (because the IDE doesn't care that suddendly your gcc in PATH is in $HOME/.guix-profile/bin, or that pkg-config picks up packages in PKG_CONFIG_PATH which happen to be in /gnu/store/3248235325322332w-wrwqewewtew-libpng/lib/pkgconfig)).

Personally, I containerize the weird build tools I can't fully trust (vendor toolchains etc) and have wrapper scripts (written in bash) in PATH. The IDE is none the wiser that those are containerized.

It's possible to have multiple packages in a permanent custom profile, if that's what you mean (that's kinda the manifest stuff at the end of the article). Those can be started all in the same container. For example, yes, you can have a profile which contains java-eclipse-jdt-core, gcc-toolchain and gfortran-toolchain for your specific project. This does not change your specific project's package.

If you are asking whether java-eclipse-jdt-core, gcc-toolchain and gfortran-toolchain would be referred to in your guix.scm, I wouldn't do that. But in your profile? yes.

>Would one need to install the IDE as a dependency of a project?

Why that? The IDE, like a text editor, is a developer tool and doesn't end up with the project artifacts that you are building. So it's not any kind of dependency of the project.

For example when you build Java projects using Eclipse, your projects are actually built using gradle and then openjdk. So gradle is a native-input, openjdk is a build system input and Eclipse is NO dependency of your project's guix package.

Your developer profile, however, can contain multiple packages (in the container). That's not what's built when you build just the package using "guix build -f guix.scm", though (those builds are isolated).

Think of a profile as something like as set of packages and also environment variables that you can refer to as a whole (containerize etc) using a new fixed name.

Or think of companies where you have different hats on. Depending on the hat, you would have a profile--so the developer hat doesn't actually have the tools to delete production :)

Most other distributions have just one global profile, not even per user. In guix, you have a default profile ".guix-profile" per user, and you can make any number of extra ones (no sudo needed).

>when you have multiple projects with different dependencies open at the same time?

Hmm, I think I can see what you are getting at. I don't know whether there are IDE plugins that are guix-aware. Would be easy to do though (it would just use a custom build step as the only build step - "guix build -f guix.scm" . This automatically makes a container with your package, its build system and your package's dependencies in it and builds that (if dependency is not built yet, makes a container with that package and its dependencies in it and builds that, and so on, recursively). The IDE would then pick up the output of "guix build" which is the path to the result (somewhere in /gnu/store/...)).

The path names used inside and outside the container are the same, and the dependencies are kept around for a while, so the IDE will have a good time referring to those for headers etc when debugging or doing autocomplete.


Somewhat un-guixy-but-easy way to get started in:

    $ mkdir -p ~/profiles
    $ guix package -p ~/profiles/developer -i gcc-toolchain gfortran-toolchain emacs
    $ guix shell -p ~/profiles/developer --check
    (env)$ cd yourproject # which has guix.scm inside
    (env)$ emacs
    (have emacs do "guix build -f guix.scm" in there from time to time)
This creates a new profile "developer" (you might want that to be more granular eventually, but whatever) with the 3 packages inside and then starts a shell inside that profile. You will have access to those inside that shell (only guarded by PATH etc), but you will ALSO have access to all the tools-outside-that-shell.

If you want to containerize, you can do that, too. Note that then you won't have any of the usual packages, including coreutils, available (no "ls" :) ):

    (env)$ exit
    $ guix shell -C -p ~/profiles/developer --check
    (env)$ ls
    sh: ls: command not found
    (env)$ exit
    $ guix package -p ~/profiles/developer -i coreutils
    $ guix shell -C -p ~/profiles/developer --check
    (env)$ ls
It works!

    (env)$ guix
    sh: guix: command not found
Well, that can't be good.

    (env)$ exit
    $ guix package -p ~/profiles/developer -i guix
    $ guix shell -C -p ~/profiles/developer --check
    (env)$ guix build -f guix.scm
It works!

Note that the "-C" automatically also exposes the current directory that "guix shell" saw when starting up to the container.


The manifest stuff is so you can have a more declarative way to specify packages (think Cargo.toml instead of mutable Debian installation).

    (env)$ exit
    $ guix package --export-manifest -p ~/profiles/developer
    (specifications->manifest
      (list "guix"
            "coreutils"
            "emacs"
            "gfortran-toolchain"
            "gcc-toolchain"))
    $ guix package --export-manifest -p ~/profiles/developer > yourproject/manifest.scm
    $ guix shell -C -m yourproject/manifest.scm
    (env)$
Works the same as before. Now more declarative. And you can throw away ~/profiles/developer* now, it will be rebuilt each time (with caching, don't worry).


The whole thing is enticing. I'm looking at it as a replacement for tool version managers like NVM, pyenv, asdf and probably as a replacement for local Docker. There is, however, a doubt that I might fight it more than I would benefit from it. After all, the IDEs were not designed to work in Guix environment. There is no way to tell without trying, I guess.


It depends on your use case.

For example, .NET core is nonexistent in Guix and nobody in the community seems to have any use for it. Also, there's an upstream bug report in dotnet core stating that it doesn't have functioning bootstrapping (AT ALL), and Microsoft doesn't care.

Java bootstrapping in Guix actually works pretty well, but only up to (and somewhat excluding) Maven. Everything higher than that is extremely difficult to build without cheating.

So I'd say if you use C, C++, Rust, Scheme, Haskell, R, Python, Ruby, Perl or stuff like that, Guix is awesome.

For Java with Ant, it's ok (something like 20 different Java VM and JDK packages are in guix, so you can do everything Java can do).

For Java EE, it's doable but convoluted (just install binary IntelliJ community edition from IntelliJ's website, for example). I'm using that myself, on Guix, and it's ok.

For .NET, ha ha, better be prepared to use mono from Xamarin. Realistically, .NET is not working. .NET IDEs? Nope.

>After all, the IDEs were not designed to work in Guix environment

It depends on how much they need to be designed for that. It works very well for IntelliJ, and I don't think that IntelliJ can tell at all that it's inside a guix profile.

What is true is that IDEs could make more use of the EXTRA power that guix gives (like guix build --with-source and guix build --with-patches in order to automatically patch dependencies for quick tests), and it's totally annoying that they don't.

Note that Docker is also available in Guix, both the actual daemon (not that guix uses it...) and as a guix build output target.


In Nix each project gets it's PATH updated to project specific absolute paths in the Nix store.

This is automated with direnv and an extension for direnv in your ide so this transparently happens when you open that project.

tl;dr Ide plugin to use same PATH and stuff as nix develop


If only it worked on anything other than Linux.


It works on top of any Linux distribution.

So you can for example use WSL2 on Windows with a small Linux distribution and then extract the guix binaries from the website guix.gnu.org onto there, start guix-daemon in there and use guix like that. That said, I care about bootstrappable builds, so I can't recommend using a hypervisor I can't trust (Windows Hyper-V) as a base.

That's if you want the development environment.

On the other hand, for using guix packs of your software, you don't even need to install guix. Just unpack the pack as-is (or use docker).

Note: guix supports cross compilation, so you CAN just use --target=x86_64-w64-mingw32 and it will compile your program for Windows native just fine. The computer that is doing the building needs to be Linux- or Hurd-based, though.

Sometimes people come and try to port guix to cygwin or whatever but I have no experience in how far that is.

What's your use case?


Actually Guix System also runs on GNU Hurd. Also one might try porting it on kFreeBSD as well.


Although it is not the Guix, Nix supports:

    x86_64-linux
    aarch64-linux
    i686-linux
    x86_64-darwin
    aarch64-darwin
Perhaps some day this will also be possible for Guix, but I don't think it fits the ideology of Guix since MacOS isn't free (not as in beer).


> Perhaps some day this will also be possible for Guix, but I don't think it fits the ideology of Guix since MacOS isn't free (not as in beer).

I just wanna note here that the hesitation to invest in macOS support in the Guix development community is technical as well as ideological. macOS is a difficult platform to support for third-party package managers, and developer interest in macOS support is a difficulty within the Nix community, too. There's a lot of breakage on major macOS upgrades as well as some fundamental portability and hermeticity problems on the platform.

That said, (as an outsider) I think it would be awesome if Guix ran on macOS, just like it's ultimately a good thing for the world and for GNU that Emacs runs pretty well on macOS.


I've had some luck in building it on MacOS with brew, however, the investment of learning MacOS dynamic linker is too costly at the moment, and it seems to be a blocking issue right now


There seems to be a lot of Mac hackers on HN! Maybe comments like yours will eventually inspire someone with the chops to play around and advance things.

It'd certainly make for a good blog post here. :)


Guix builds binaries for

    - x86_64-linux
    - i686-linux
    - aarch64-linux
    - powerpc64le-linux
    - i586-gnu


Slight nitpick, Nix does support more architectures, but those are the ones with prebuilt packages. Compiling say 32 bit ARM is quite feasible, takes roughly a day for a full OS image.


This is the only reason I haven't tried to use Guix. I love the concept, I want to use it, but it does not run on FreeBSD. And I would not invest time in a packaging system that works on my workstation but not on my servers.

It is sad to see so many Linux only software, especially when there is no technical reason not to support *BSD.


> when there is no technical reason not to support BSD.

Guix' packages include glibc in their dependency chain, so unless you can use glibc on BSD, there is your technical reason. For example GNU Hurd is supported in addition to Linux.


I feel this. My love for BSD almost matches my love for Nix, it's unfortunate I have to choose one or the other.

I'm aware Nix is closely integrated with SystemD, so availability on BSD will probably never happen (though perhaps you could use the Darwin code as a starting point?), but I'd be curious to know what in particular limits Guix from being ported.


Wait it's integrated with SystemD? What is a package management system doing with the init process? I now remember that Guix is a daemon, something that made me really wary at the time; but a SystemdD dependency is something else entirely.


NixOS can be validly viewed as a very fancy Systemd configuration toolkit. If you think about it, ultimately an instance of a modern general-purpose OS is structured as a set of services which are described for and orchestrated by, well, something. In the case of NixOS (not Nix in general!) that something is Systemd (which also happens to be used by all other major Linux distros); in the case of GuixSD that something is GNU Shepherd (which also happens to be used by GNU Hurd)


Nix is also generally run as a daemon. It doesn't have a dependency on systemd and it does run on MacOS. I think also it runs on FreeBSD in principle.

The parent poster was probably conflating NixOS and Nix. NixOS is a way of using nixpkgs to build/configure and install/upgrade an operating system based on Linux and systemd. But you are not obligated to use systemd just because you're using nixpkgs.

NixOS uses sytemd for essentially the same reason other Linux distributions do: most user environments are now built with the assumption that systemd underlies them if Linux does as well. In principle you could fork nixpkgs and make all the necessary changes to remove the systemd assumption - managing a NixOS system and hacking on nixpkgs are basically the same skillset so it's not like managing an Ubuntu system where you would have to become familiar with how Ubuntu gets built. With nixos, the command is the same whether you're building an entirely new distribution based on a custom fork or whether you're just downloading builds of the latest security upgrades. Aside from the actual energy it takes to maintain a second system manager, you would only have to wait for the builds to complete rather than learning how to build everything. But so far no-one who has tried that has got enough traction - the cost-benefit just isn't there. Honestly, I think this is part of the reason people are offended by NixOS in particular using systemd: it feels like it should be possible for you to remove the systemd dependency, but you haven't done it.


Nix isn't, but NixOS is, if I'm not mistaken.


Sorry, yes, I was mixing up Nix and NixOS :)


I love NixOS, but I am looking to move my workstation to Guix.

The reason is that, it seems NixOS do not sign their packages. I've checked the messaging platforms, and while there seems to be a consensus that its not needed, I'm at present unconvinced (especially since Guix, to my knowledge, do require signing).

On its own I'd actually be OK with looking past this, but the lack of documentation on mandatory access control, secure boot, and general sandbox consideration, makes me concerned on multiple fronts. Which is a shame, because like I said, NixOS is a delight to use.


To be clear, I think Nix (like Guix) signs its pre-built binaries ("substitutes").

However, only Guix has signed commits in its repository (the repo contains package definitions) and a mechanism for secure updates: https://guix.gnu.org/en/blog/2020/securing-updates/

The problem goes well beyond though: as far as I know, Guix is the only project that has a Git repository that users can authenticate when they pull from it.


What's the split like these days between users of Guix the package manager running on some other distribution vs Guix the distribution? Is one noticably more popular than the other?


There are many users of Guix at research institutes who aren't running Guix System (i.e. the full system). But the difference between Guix and Guix System is pretty small; even with just Guix you get the "guix system" command, so you can build containers and VMs that run Guix System. You only can't benefit from full-system rollbacks and the integration of Guix system services.


Guix generally feels much saner than Nix but guix upgrade is shockingly slow.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: