What is Nixpkgs preferred programming language?

In nixpkgs in most cases have bash under the hood, but in more complex cases we use other languages:

  • Perl (it is all over the place)
  • Python (if I recall correctly /boot setup is written in Python)
  • Rust (I think we have it somewhere in init, maybe for the secure boot?)

Perl seems to be slowly deprecated, but what are the preferred programming languages for cases when expressing things in bash is just too complicated?

I would love to see documentation on this if something like this has been decided, if not - would anyone be interested in creating an RFC?

7 Likes

In depends on what the task is but generally the best language is one that doesn’t cause a lot of additional bootstrapping. If the language is interpreted then it saves a compilation step. Perl is pretty deep in the internals of Nixpkgs so Perl can often be the practical choice.

1 Like

Given that most of Nix tooling is being written in Rust these days, it feels like a future-proof bet.

6 Likes

So, the real answer here is bash :stuck_out_tongue: The vast majority of interesting program logic in nixpkgs is bash scripts inlined in Nix code.

But when you need to leave bash, my impression is that Python and Rust are very much the preferred languages for any new bespoke nixpkgs programs. Python for its decent balance of ease-of-use and quality, and Rust for its (IMO) significantly higher quality. Rust vs Python comes down to which one’s tooling seems more appropriate for the task, and honestly author’s preference. Like I wouldn’t personally write systemd-boot-builder with Python if we redid it from scratch, but I think it’s a perfectly reasonable choice.

(My actual preference most of the time would be Haskell, but I generally don’t want to force fellow nixpkgs maintainers to have to work with Haskell code)

And Perl is on its way out. Nothing new is being written in Perl and a number of Perl things are slowly being replaced with other things.

15 Likes

So the answer is there’s no consensus and you can use whatever fits your preferences (and the preferences of the reviewers, naturally) and the use case of the tool. If you want there to be consensus then it’s RFC time.

5 Likes

yeah, that’s basically my issue. I don’t like that nixpkgs uses ‘whatever’. Probably it would be best to standardize on some lisp like janet or ruby/lua/luvit, due to them being small, interpreted, easy to bootstrap but afaik they aren’t used in nixpkgs at all

I would love it if someone did an RFC for this, I’d be down to be a shepherd but I’d rather avoid taking ownership of it since this feels like a can of worms

@ElvishJerricco, also if I recall correctly haskell requires like 5gb of toolchain to compile anything :sweat_smile:

I was thinking about it, wasm might be a very solid option that would result in next to no conflicts in the community

Wasm isn’t a programming language. It’s a compiler target. We can’t be shipping precompiled wasm blobs in nixpkgs, so you’re back to square one with needing to choose a language to compile to wasm.

7 Likes

Is there any reason why cant we just commit blob in, add CI verification that it matches the source code and be done with it?

if we can do that, language could be whatever anyone feels like it

Size would be an argument against it, but I doubt that it would be that big

wasm binaries are regularly several megabytes large.

CI verification and wasm don’t improve anything at all in this case. Maintainers still need to work on and review the source code. That is fundamentally unavoidable.

6 Likes

A compiled language, or wasm, has at least the advantage of not bloating the runtime closure, even if can bloat the build-time one.

I suppose Guix is what happens if you’re going all in for one language :slight_smile:

4 Likes

oof, I did not expect wasm binaries to be that large

I feel like language itself matters the least, at least if its procedural. In that case even peeps who arent familiar with the language can maintain it. FP is quite popular in this community, may not be an issue as well but yeah…

Isn’t that the point of this discussion?

3 Likes

Now it’s getting close to stabilizing, I’m going to chuck Oils out there as a left-field option too. Bash-compatible (and in fact has uses as a bash ‘linter’) by default, with extra functionality that can be incrementally enabled, including very python-like expressions. Might be a way of writing light, low-dependency scripts without falling into some of the more horrendous bash pit-traps…

6 Likes

It’s arguably hard to end up with a runtime that entirely lacks python anyway, though, let alone (ba)sh.

I think a broad policy would be somewhat overbearing. It’d make zero sense to enforce Rust to handle the emacs modules, for example. I figure contributors know their use cases well enough, and reviewers are there to catch obviously dumb ideas.

This will naturally gravitate towards the most popular languages + bash - which I’d argue is good, since those will be most accessible, too.

Rust and Python definitely seem like pretty good contenders for the most generally accessible languages out there atm, though I’m a bit surprised there isn’t more go in nixpkgs. I guess its build system is a bit of a pain in nix contexts, but Rust isn’t that much better.

Haskell & co. may seem like a natural fit, especially given how many folks in the community are involved with it, but IME there are enough people out there who have never touched a functional language (or have and have refused to since, to the point that nix already scares them enough) that it would significantly reduce the number of people contributing, which is probably not a good thing.

6 Likes

FWIW Nixpkgs is using extremely niche bash/shell features at times and Oils sadly lacks some Bash features to make it work smoothly (biggest being let).

I’ve been tinkering with replacing Bash with Oils in the stdenv in a repo I called oily-nixpkgs and I think I’m not too far from being able to build bash with the huge bash cruft it requires.

I just had my second child and some other private things keeping me busy but if some more people would be interested in pushing this with me I’d gladly start picking it up again.

I’m sure Oils can replace at some point even Python scripts. But it’s not going to replace things which require binary operations and the like. IMO using Oils for ‘higher level’ (e.g. strings/commands as output) and Rust for lower levels is good enough.

10 Likes

Am I crazy for thinking Rust isn’t suitable for the same reason as Haskell? It’s difficult and not that popular.
Python is at least easy to pick up and much more in use.

1 Like

As was discussed in the nix-windows thread, I still think nushell is the best option I’ve heard of for trying to promote a new baseline for scripts in nixpkgs.

Particularly, it works on Windows, as well as the unixes.

I like the momentum of switch-ng, etc using Rust. But there’s a lot of last-mile scripts that don’t suit themselves to compiled languages in general; I think nushell scripts are a good fit. I’ve pretty much been authoring new scripts in nushell for over a year and am happy (despite some churn).

(To steelman my own suggestion, nushell still changes things between releases that would be annoying or worse. And it lacks trap, though I’m guessing that’s rarely used in these types of glue-y scripts)

5 Likes

At least among nixpkgs maintainers, Rust seems quite popular. And I think Haskell is significantly more problematic for people to pick up, because it has very little common ground with familiar imperative languages. I think Rust is honestly much more similar to Java or especially Swift than it is to Haskell. So I think it’s much easier to pick up, if only because of familiarity. EDIT: Then again this is Nix we’re talking about, where some of the unfamiliarity of Haskell is already present in the Nix language itself.

5 Likes

Adding to this, there is this proof of concept for using Nushell as a builder GitHub - DeterminateSystems/nuenv: A Nushell environment for Nix

1 Like