Nix Language Quirks
with and let
with gets less priority then let. This can lead to confusions, especially if you like to write with pkgs;:
nix-repl> pkgs = { x = 1; }
nix-repl> with pkgs; x
1
nix-repl> with pkgs; let x = 2; in x
2
So we see, that let binding overrides with binding. But what about this?
nix-repl> let x = 2; in with pkgs; x 2
Nah, with and let have different priority when resolving names.
Old let syntax
This is an old Nix syntax, that probably isn't used much
nix-repl> let { x = 1; y = x + 1; body = y; }
2
It is equivalent to modern syntax expression let x = 1; y = x + 1; in y. Note, that it doesn't require rec keyword.
Note, that it isn't equivalent to with rec { x = 1; y = x + 1; body = y; }; body because of mentioned with and let quirk, but is same as rec { x = 1; y = x + 1; body = y; }.body
Something that looks like both record attribute and let-binding
Destructuring function argument - is a great feature of Nix.
nix-repl> f = { x ? 1, y ? 2 }: x + y
nix-repl> f { }
3
The fact that we can add @args argument assignment is also cool
nix-repl> f = { x ? 1, y ? 2, ... }@args: with args; x + y + z
nix-repl> f { z = 3; }
6
But don't be fooled, args doesn't necessarily contain x and y:
nix-repl> f = { x ? 1, y ? 2, ... }@args: args.x + args.y + args.z
nix-repl> f { z = 3;}
error: attribute ‘x’ missing, at (string):1:30
These x and y are in fact let-bindings, but overridable ones.