The mentioned home-manager is more of an awkward hack than a good solution in my view. Tt's not actually immutable, but just dumps down files into $HOME,
That's actually not true. Each home-manager generation is immutable and in the Nix store. E.g., the last two generations on my MacBook:
home-manager generations | head -n2
2019-12-23 12:05 : id 12 -> /nix/store/6rig5ip0swmnnfcvgm221n5lig3xsh18-home-manager-generation
2019-12-12 12:40 : id 11 -> /nix/store/8as4k5x7i5bhf3wjvlcczhx8w2680k46-home-manager-generation
But it symlinks certain files from the store in the home directory, because some programs (e.g. shells) have hardcoded paths to configuration files.
losing the most interesting aspect of Nix
Similarly to the declarative NixOS configuration, you can switch between home-manager generations, etc. It's a purely declarative configuration.
It also basically builds up a parallel package repository that you have to use besides the actual packages,
What do you mean by this? home-manager also uses the Nix store. E.g., my home-manager configuration contains ripgrep in the declarative package configuration:
There is plenty of documentation, but it is often incoherent, messy, missing important explanations,
I fully agree! Often one has to read derivations in nixpkgs to understand how things are done.
The language... It is full of oddities and basically a mess
I disagree. I didn't like it when I started using Nix and seriously looked at Guix because it used scheme. Now, 1.5 year later, I like Nix as a language. It's just a small, functional language.
---
I think the biggest barrier of the Nix ecosystem is that you can't really use NixOS or Nix in a meaningful way without also learning the Nix language and some of the intricacies of writing derivations. So, you are pretty much all-in or it will be a frustrating experience. So, I understand your point about only using NixOS on reproducible servers. I also use NixOS on my desktop (and love it), but admittedly, it's only doable when you invest enough time to learn things.
If someone wants an immutable system with transactional installs and updates, Fedora Silverblue is probably a much easier entry-point, because you do not really have to understand OSTree et al. to use it.
Nix as a language is tiny. If you know functional programming at all you won't have any trouble with it and can "learn" it in days if you put in the effort. NixOS isn't complicated because of the language.
I don't know Gluon (from a quick glance, it looks similar to Haskell and ML). But I do not think it will help much. Nix is a small, lazy, functional language. Being a lazy functional language, it will be more difficult for people without a FP background. But laziness and purity provides a lot of benefits.
I think the problem is more about documentation and expectations:
- Nix only has a small number of builtins. A lot of useful functions are in nixpkgs. As a consequence, you often have to look in two places to find if there is an existing function that does what you want to do. Added to that, some functions are undocumented and can only be discovered through the REPL or by reading the relevant nixpkgs sources. Then some functions do have documentation, but the documentation is very terse, does not contain good examples, etc. I think things would be clearer if Nix had a documented standard library and nixpkgs would only be focused on providing package derivations and NixOS modules.
- Expectation-wise: I think a lot of people do not expect to have to learn a new language when starting to use a package manager and/or distribution. This leads to treating derivations akin to RPM spec files (which is what I did in the beginning), which becomes frustrating very quickly.
Disclaimer: I am by no means a Nix expert. These are my observations from learning Nix myself since last year.
Nix is a small, lazy, functional language. Being a lazy functional language, it will be more difficult for people without a FP background. But laziness and purity provides a lot of benefits.
Many functional languages have lazy evaluation, and they do provide benefits. However, unfortunately, this concept has leaked into other areas of programming. In particular, many database ORMs use lazy evaluation to pull data. In one step, you create a database query, then pass that off to another function or class. Then, when it's off in another package and evaluated the query is made.
The main problem with lazy evaluation of database queries is that it treats a database evaluation like normal code, even though under the hood there may be network access, caching, and if you're not careful duplicative database pulls.
Generally, there should be a rule in programming languages that when you make a network call, the programmer has clear visibility into when that is happening. Hiding it with fancy syntax is more of a negative than a positive.
Comments
The mentioned home-manager is more of an awkward hack than a good solution in my view. Tt's not actually immutable, but just dumps down files into $HOME,
That's actually not true. Each home-manager generation is immutable and in the Nix store. E.g., the last two generations on my MacBook:
But it symlinks certain files from the store in the home directory, because some programs (e.g. shells) have hardcoded paths to configuration files.losing the most interesting aspect of Nix
Similarly to the declarative NixOS configuration, you can switch between home-manager generations, etc. It's a purely declarative configuration.
It also basically builds up a parallel package repository that you have to use besides the actual packages,
What do you mean by this? home-manager also uses the Nix store. E.g., my home-manager configuration contains ripgrep in the declarative package configuration:
There is plenty of documentation, but it is often incoherent, messy, missing important explanations,I fully agree! Often one has to read derivations in nixpkgs to understand how things are done.
The language... It is full of oddities and basically a mess
I disagree. I didn't like it when I started using Nix and seriously looked at Guix because it used scheme. Now, 1.5 year later, I like Nix as a language. It's just a small, functional language.
---
I think the biggest barrier of the Nix ecosystem is that you can't really use NixOS or Nix in a meaningful way without also learning the Nix language and some of the intricacies of writing derivations. So, you are pretty much all-in or it will be a frustrating experience. So, I understand your point about only using NixOS on reproducible servers. I also use NixOS on my desktop (and love it), but admittedly, it's only doable when you invest enough time to learn things.
If someone wants an immutable system with transactional installs and updates, Fedora Silverblue is probably a much easier entry-point, because you do not really have to understand OSTree et al. to use it.
If nixos used a different language (e.g. gluon), do you think you would have become more comfortable quicker?
Nix as a language is tiny. If you know functional programming at all you won't have any trouble with it and can "learn" it in days if you put in the effort. NixOS isn't complicated because of the language.
I don't know Gluon (from a quick glance, it looks similar to Haskell and ML). But I do not think it will help much. Nix is a small, lazy, functional language. Being a lazy functional language, it will be more difficult for people without a FP background. But laziness and purity provides a lot of benefits.
I think the problem is more about documentation and expectations:
- Nix only has a small number of builtins. A lot of useful functions are in nixpkgs. As a consequence, you often have to look in two places to find if there is an existing function that does what you want to do. Added to that, some functions are undocumented and can only be discovered through the REPL or by reading the relevant nixpkgs sources. Then some functions do have documentation, but the documentation is very terse, does not contain good examples, etc. I think things would be clearer if Nix had a documented standard library and nixpkgs would only be focused on providing package derivations and NixOS modules.
- Expectation-wise: I think a lot of people do not expect to have to learn a new language when starting to use a package manager and/or distribution. This leads to treating derivations akin to RPM spec files (which is what I did in the beginning), which becomes frustrating very quickly.
Disclaimer: I am by no means a Nix expert. These are my observations from learning Nix myself since last year.
Many functional languages have lazy evaluation, and they do provide benefits. However, unfortunately, this concept has leaked into other areas of programming. In particular, many database ORMs use lazy evaluation to pull data. In one step, you create a database query, then pass that off to another function or class. Then, when it's off in another package and evaluated the query is made.
The main problem with lazy evaluation of database queries is that it treats a database evaluation like normal code, even though under the hood there may be network access, caching, and if you're not careful duplicative database pulls.
Generally, there should be a rule in programming languages that when you make a network call, the programmer has clear visibility into when that is happening. Hiding it with fancy syntax is more of a negative than a positive.