These are my notes from the Reading Nix expressions
talk in NixCon 2019.
Nix package language has a similar syntax to the “JSON meets functional language concepts”. E.g. you have Let-expressions which I would say is a functional concept (ref: https://en.wikipedia.org/wiki/Let_expression) – I first saw it in Elm and Haskell.
An important thing to keep in mind is that Nix is a lazy language so some code might not get evaluated if it is not called. This means you can actually read the code from the “middle”. For example, you can start reading this config https://github.com/jwiegley/nix-config/blob/master/default.nix in line 12 and then continue to the next one. Once you see a variable like e.g. ${version}
you can “evaluate” it in your head (in this case version is defined in line 1).
The point is that some variables/functions can be defined but might not get called so Nix won’t evaluate them. This is completely different from how e.g. Python works.
Functions
Nix functions are just lambda expressions. Example:
a: b: a + b
Another representation is keyword arguments or a set pattern:
{ a, b }: a + b
This one is the most popular. You can call this function with a
and b
attributes. If you need additional arguments you can use an ellipsis (...
):
{ a, b, c, ... }: a + b + c
This will work on any set that contains at least the three named attributes.
Ref: https://nixos.org/nix/manual/#ss-functions
Builtins
Nix expression evaluator has a bunch of functions and constants built in. For example:
- toString e (Convert the expression
e
to a string) - import path (Load, parse and return the Nix expression in the file
path
) - throw s (Throw an error message
s
. This usually aborts Nix expression evaluation) - map f list (Apply the function
f
to each element in thelist
list)
There are tons of other builtins available.
Keywords
We have several reserved keywords in Nix:
rec
(Recursive sets) Use recursive sets if you need to use the variables inside the set.let
(Let-expressions) When you need to define a local variable.inherit
(Inheriting attributes) Used inlet
expression.inherit x;
is a shorthand forx = x
.if
(Conditionals) Good old if condition.assert
(Assertions) Same as Python assert.with
(With-expressions) The most common use ofwith
is in conjunction with the import function.
Operators
Nix also provides a bunch of operators like Arithmetic addition, subtraction, division, etc.
See this link for the full list of operators.
This is the very basic of the Nix language. You will need the above knowledge if you will want to start hacking nix config files. Or should I say if you want to know what you are actually doing while hacking nix config files 🙂