Announcing Snix
46 points by domenkozar
46 points by domenkozar
I recognize many of those words.
For nix there is:
Am I missing anything? It really feels like that XKCD comic out there.
Probably more like:
In practice:
The first three are separate for social reasons mostly, the others exist because they want to take a different direction in the actual software.
Lix also has one extra experiment: pipe-operator since v2.91 (August 2024).
I love that feature dearly and use it in my personal config to avoid deeply nested expressions: h z (g y (f x)) == f x |> g y |> h z
lib.pipe (f x) [ (g y) (h z) ]
Not saying a pipe operator is bad, but we have an option now with ‘good enough’ ergonomics. Does the pipe operator offer some performance gain by being in the language?
Not sure about performance, but having just written a bunch of Nix code using |>
, I much prefer the operator over lib.pipe
for aesthetical reasons:
([ "${pkgs.ai-robots-txt}/robots.json" ] ++
((builtins.readDir "${pkgs.extra-agent-list}/share")
|> lib.attrNames
|> (map (filename: "${pkgs.extra-agent-list}/share/${filename}"))))
|> inputs.nixocaine.lib.processRobotList
|> (map (builtins.replaceStrings [ " " ] [ "\\s" ]))
|> (lib.concatStringsSep "|")
I don’t even want to translate it to lib.pipe
, it would not be much of an improvement over the original, pipe/operator-less form. I do not find lib.pipe
’s ergonomics “good enough”.
I used lib.pipe
before enabling the experiment, and I like that function too! I just like the pipe syntax even more.
I’m using it in my personal config, which no-one else ever uses/sees, just for the syntax. And lib.pipe
is the obvious, and easy to switch to, off ramp if I need it in the future.
Performance is one of the RFC’s unresolved questions and I haven’t noticed a difference because most of my config eval time is not spent in lib.pipe
.
I don’t want to duplicate the whole RFC or its discussion here, but having the functionality in the language has other UX benefits like better tracebacks.
I hadn’t seen the RFC.
There is reason to expect that replacing lib.pipe with a builtin will reduce its overhead, and that the builtin should have little to no overhead compared to regular function application.
This is precisely the advantage I could see if it were a built-in—otherwise the value add is pretty slim to keeping it simple just sticking with lib.pipe
(& I say that having used pipe-like operators in PureScript, Elm, OCaml, Haskell, & Nickel and a fan of operators). Recently tho I’ve been coming to the opinion that our function notation sucks & should be post-fix by default ala reverse Polish notation.
Not nix, but similar/related: https://brioche.dev/
Guix is an unrelated implementation of the same idea as Nix, using Scheme as the configuration language instead of Nix.
Guix started as a Nix fork, so I wouldn’t say it’s an unrelated implementation
Guix is not a fork of Nix.
My source is:
https://en.wikipedia.org/wiki/GNU_Guix#History
and a tool to instantiate and manage Unix-like operating systems, based on the Nix package manager
https://lists.gnu.org/archive/html/gnu-system-discuss/2012-06/msg00003.html
Ludovic aka address@hidden starded a project implementing nix package definitions in scheme/guile: https://gitorious.org/guix
I don’t know how much code it shared, but most people seem to say it started as a fork
It did, it took the Nix daemon and modified it. For some time they were still subject to the same CVEs. There’s been an effort to rewrite the daemon in Scheme, but no idea how that’s going (maybe it’s done?).
For some reason a few Guix-affiliated people refuse to acknowledge that they forked the Nix daemon, it’s probably something political.
The nix daemon is a very small piece of the overall system. That piece was borrowed, indeed, but 99% of the system is not that. It is an otherwise completely separate implementation of the functional package management paradigm that makes some radically different design choices. The daemon thing is a distraction. Guix is not a fork of Nix in any way that matters.
Is it bad to have many implementations? Genuine question, I don’t know. People also attack Rust for having only 1 serious implementation.
The politics are a little sour here and there, which is probably the biggest downside. Otherwise, good point. The Lix and Snix ports seems really healthy and forward looking. Maybe it causes some confusion for non-NixOS users? But in NixOS, most probably use whatever they are fed by the base system.
I think the danger is that they might start diverging on Nix-the language and we get incompatible Nix repositories. This is already the case to some extend with e.g. flakes (though cppnix/lix/determinate all support them), but could get worse if implementations start adding implementation-specific features.
I think this risk is real, and is currently mitigated primarily by one thing: The steadfastness of nixpkgs maintainers in refusing to accept code in the packages that doesn’t work in Nix 2.3 - which is ancient at this point.
What I can see happening is a sort of Cambrian explosion of Nix implementations and dialects, but with a shared minimal viable subset in “whatever is needed to use nixpkgs”. Sort of like the situation with C, where a bunch of compilers all implement the ISO/IEC standard but also offer a ton of nonstandard extensions, with nixpkgs acting as somewhat of an ad-hoc standards body.
I think it would be helpful if there was some indication of who is actually working on this vs. the original repo. Is this where the main development effort will take place? Is this meant to develop in parallel with Tvix the way Lix et al. are supposed to develop in parallel with Nix?
As someone who actually played around with Tvix, I appreciate this development. The project is technically exciting, but the monorepo with mostly unrelated code and the very strong connection to the TVL community made it seem less accessible than it maybe is.
If you want to understand the ideas behind Nix’ model, it is much easier to do so reading the Tvix (now Snix) code compared to Cppnix and Lix. Have a look at the protobuf definitions and watch flokli’s talks on Tvix. I believe he is also the author of the linked website.
I hope Snix can take off, because it really brings a lot of benefits (e.g. much finer cache granularity).
Is Snix keeping Gerrit? That was such a massive productivity improvement over the pull request model.
We do use Gerrit for Code Review. It allows a more granular review (per-commit granularity rather than PR granularity), as well as keeping track as how commits change over time. It greatly simplifies the review process, and leads to overall more high-quality contributions.
Looks like it!
From the TVL side there’s some context in this bug: https://b.tvl.fyi/issues/431
Tvix & Snix have conflicting priorities (as laid out in the post), and the best way forward is probably this split. The plan for Tvix is to add a store implementation that works in a more “traditional” way (i.e. become a 1:1 cppnix replacement), whereas the research and store optimisations (content-addressed storage etc.) will continue to be developed in Snix.
There was a comment I read about a year ago about Tvix having Windows in mind, but it not being a priority.
The libnix
project also evaluated Tvix at once point, but concluded that it was “too early for considering tvix to ‘building software using nix’ on windows”.
If Snix carries forward the interest in “keeping Windows in mind” (to whatever extent), with some mentorship and guidance, I would be interested in working on any issues that would make building with Nix on Windows a reality in the future.
I’ve been working on Nix on Windows in CppNix. I recently got most unit tests passing in CI using Wine. There’s still lots to do (e.g. actually implementing a builder) but I’m making good progress on a continuously integrated and tested platform.
If you want to help: https://matrix.to/#/!GmJrQRmEoTfulqyDge:nixos.org?via=chat.home.brianmckenna.org&via=matrix.org&via=beeper.com
Looks like the RSS feed also includes the documentation, not just the blog posts.