Let’s imagine for a moment that you could turn your whole Nix expressions, configs, dev shells, packages and everything automatically into a different language X and everything would keep working the same; you could still do nix-build, nix-env, nix run, and everything you are used to, just that now you would be reading, writing and maintaining code written in language X instead of NixExpressionsLanguage
Lisp’s style is to imperative for me, though it is powerfull… I do not think I’d use it for a declarative system like nixpkgs.
Dhall is pretty much like nix, except that I hate how it deals with some things when we have a “Dict[str, Any]”…
Nix is nice, but has it flaws…
And I never used nickel.
So I’d prefer to stay with nix among those 4…
Though if I had a wand and was able to change the underlying language right now, I’d choose for an Haskell or ML dialect that was adjusted to our needs.
Native map syntax to replace sets
Top-level expressions, such that a file does not need to be a module, but can “return” a function straight
of course it also needs to be adjusted such that callPackage idioms can be kept
and the typing needs to be weakened/adjusted to allow for a bit of flexibility, such a packageset can be defined without using (explicit) enumerations…
I always feel like such surveys are rather inconclusive, because people will only vote for choices they are familiar with. The best choice might be the most unpopular one, but it loses because so few people can vote for it. So it’s a popularity contest to some degree.
A better approach would be to have a two-staged survey, where the first stage asks “which of these choices are you familiar with?”, and the second stage asks you to choose the best among the ones you selected in the first stage (or ranked choice, etc.)
Then you can have conclusions like “Among people who are familiar with X and Y, 90% prefer X over Y”
+1 to adding type annotations so that it’s quicker to find where a mistake was made.
especially for when you’re trying to be clever and DRY a bunch of stuff.
I kinda like the diagram in “Configuration Complexity Clock”; if you consider the trade-offs: at a certain frequency of changes, configuration files are more appealing than hardcoding values; at a certain complexity, a DSL is more appealing than config files; at a certain expressiveness, hardcoding values is an improvement on an niche DSL.
Mainly I just mean that it’s easier to see that another scheme could be better without considering the costs of the other scheme.
I think it’s plausible there are common use cases for Nix where a less expressive configuration language would still provide a lot of value.
e.g. the repl-it introduction to nix is basically some nix boilerplate and a list of packages.
my nixos configuration is pretty simple; since it doesn’t introduce functions/abstractions, it’s about as easy to read as YAML.
Whenever nix or NixOS is mentioned, so the hesitation to learn a new, seemingly difficult niche language. While nix itself is easy, the nixpkgs API is not and suffers from poor discoverability and tooling/IDE support. A typed language can make the API easier to understand. In addition, PureScript can be used outside NixOS, making it more attractive to learn for new developers. With its similarity to Haskell and use in the JavaScript world, there are already many potential contributors.
Looking at the number of open pull requests, it seems that more experienced developers are needed, and making NixOS easier for non-programmers is a different problem.
My eye on a less expressive language comes from two potential users:
People who refuse nix because they hear the word “functional” or are otherwise entrenched in a familiar ecosystem and unwilling to learn a new one (which is not unreasonable for something still as niche as nix)
Non-programmers who struggle understanding the point of even small bits of syntax-related boilerplate (e.g. { ... }: { })
I don’t think that nix, the language, is too complex to use. I do think that the wider software community is overloaded with DSLs, and that it is at least perceived to be a significant amount of effort to pick up a new one like nix, even if most usage of it is not more complex than a configuration file.
A way to use something like yaml to define modules, perhaps intelligently substituting use of pkgs and config (and maybe user-defined additional args with module._args) in strings for simple expressions would put people in a more familiar context, and hopefully reduce the perceived switching cost, creating the opportunity to learn and adopt nix more incrementally.
It would also make it easier for non-programmers to build simple system configurations, which I’d love to see. Not all Linux users are programmers, and it’s a shame that they can’t try NixOS easily. I think it’s one of the best distros for such a user in theory, since upstream module maintenance can really simplify system configuration.
Such users are often really active doc/wiki contributors too, presumably because they need the tutorials, and know how to write them from the perspective of a new user. Maybe also because they lack the attrition caused by day-to-day paid software engineering
What I’m trying to say is, I think I’m most interested in this from the perspective of inclusivity, rather than avoiding complexity.
I want strong typing, but dhall has some things I don’t like. The inability to inspect Text, for example. It’s pushing towards a good thing in principle, but can leave you stranded if you’re interfacing with other people’s code that didn’t consider your usecase.
I voted for nickel in the end, since it’s better than nix that way, but my ideal would be a haskell variant, similar to what NobbZ suggested.
If it were changed to lisp I think I’d stop using nixos instantly. Not only do I hate lisp just generally, lisp is far too imperative and unconstrained for this usecase. You’d be backtracking on BOTH the typing front and the declarativity front simultaneously.
I am not sure if it is worth trying to do it more comprehensively, but apparently there are more directions than there are non-Nix choices here.
At least:
More computational power / less computational power
More typing / less typing (I guess weaker coercion checks are still possible, but maybe nobody wants them)
Syntax choices
More imperativity? (which is how people interepreted Lisp, although there is a Lisp with whatever combination of properties except for syntax by now)
Less/even more locality. One could argue that NixOS module system is not maximally local purity oriented; one could have more imperativity and more locality if imperative modification only touches special let-mut local values, and at the same time global fixpoints are restricted in some way.
Now that flakes are part of evaluation, more/less assumption hardcoding (like should Nix be trusting git more than the store in some situations? Should all fetchers/VCSes be pluggable for evaluator? Should Nix fully require the code to be formatted before evaluation?)