In my experience, the biggest problems for learning Nix (the language) are the lack of type annotations and the tendency to separate function calls from function arguments. The first time you look in `my-package.nix` you find... a dict of function arguments? I think? What the heck? What function takes these arguments? What function arguments are valid?
So you end up grepping the whole source tree for `"./my-package.nix"` just to see what functions are using it, and you find this construct:
someFunction ./my-package.nix
Which in other languages would be the slightly bizarre
some_function( eval_file( "./my-package.foolang" ) )
So you're
pretty sure these are arguments to someFunction, but it's weird that the call to `someFunction` wasn't in the same file, because it makes it hard to know what's going on.
All of this this wouldn't be so unclear if the syntax wasn't visually similar yet semantically different from most languages. The map syntax in particular looks exactly like a block in curly brace imperative languages:
{
foo = "blah";
bar = foo + "blahblah";
}
----
Fortunately, there's work to separate Nix (the tool) from Nix (the language), so that any configuration language can be used to produce derivations. Nickel has been one of the drivers of this push:
https://discourse.nixos.org/t/nickel-the-nix-language-spin-o...
https://github.com/tweag/nickel/issues/93