Nix Language
The Nix language is designed for conveniently creating and composing derivations – precise descriptions of how contents of existing files are used to derive new files. It is:
- domain-specific
It comes with built-in functions to integrate with the Nix store, which manages files and performs the derivations declared in the Nix language.
- declarative
There is no notion of executing sequential steps. Dependencies between operations are established only through data.
- pure
Values cannot change during computation. Functions always produce the same output if their input does not change.
- functional
Functions are like any other value. Functions can be assigned to names, taken as arguments, or returned by functions.
- lazy
Values are only computed when they are needed.
- dynamically typed
Type errors are only detected when expressions are evaluated.
Overview
This is an incomplete overview of language features, by example.
Example | Description |
---|---|
*Basic values* | |
`"hello world"` | A string |
|
A multi-line string. Strips common prefixed whitespace. Evaluates to `"multin linen string"`. |
`"hello ${ { a = "world"; }.a }"` `"1 2 ${toString 3}"` `"${pkgs.bash}/bin/sh"` |
String interpolation (expands to `"hello world"`, `"1 2 3"`, `"/nix/store/ |
`true`, `false` | Booleans |
`null` | Null value |
`123` | An integer |
`3.141` | A floating point number |
`/etc` | An absolute path |
`./foo.png` | A path relative to the file containing this Nix expression |
`~/.config` |
A home path. Evaluates to the `" |
` |
Search path for Nix files. Value determined by [`$NIX_PATH` environment variable](../Command-Reference/env-common.md#env-NIX_PATH). |
*Compound values* | |
`{ x = 1; y = 2; }` | A set with attributes named `x` and `y` |
`{ foo.bar = 1; }` | A nested set, equivalent to `{ foo = { bar = 1; }; }` |
`rec { x = "foo"; y = x + "bar"; }` | A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }` |
`[ "foo" "bar" "baz" ]` `[ 1 2 3 ]` `[ (f 1) { a = 1; b = 2; } [ "c" ] ]` | Lists with three elements. |
*Operators* | |
`"foo" + "bar"` | String concatenation |
`1 + 2` | Integer addition |
`"foo" == "f" + "oo"` | Equality test (evaluates to `true`) |
`"foo" != "bar"` | Inequality test (evaluates to `true`) |
`!true` | Boolean negation |
`{ x = 1; y = 2; }.x` | Attribute selection (evaluates to `1`) |
`{ x = 1; y = 2; }.z or 3` | Attribute selection with default (evaluates to `3`) |
`{ x = 1; y = 2; } // { z = 3; }` | Merge two sets (attributes in the right-hand set taking precedence) |
*Control structures* | |
`if 1 + 1 == 2 then "yes!" else "no!"` | Conditional expression |
`assert 1 + 1 == 2; "yes!"` | Assertion check (evaluates to `"yes!"`). |
`let x = "foo"; y = "bar"; in x + y` | Variable definition |
`with builtins; head [ 1 2 3 ]` | Add all attributes from the given set to the scope (evaluates to `1`) |
*Functions (lambdas)* | |
`x: x + 1` | A function that expects an integer and returns it increased by 1 |
`x: y: x + y` | Curried function, equivalent to `x: (y: x + y)`. Can be used like a function that takes two arguments and returns their sum. |
`(x: x + 1) 100` | A function call (evaluates to 101) |
`let inc = x: x + 1; in inc (inc (inc 100))` | A function bound to a variable and subsequently called by name (evaluates to 103) |
`{ x, y }: x + y` | A function that expects a set with required attributes `x` and `y` and concatenates them |
`{ x, y ? "bar" }: x + y` | A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y` |
`{ x, y, ... }: x + y` | A function that expects a set with required attributes `x` and `y` and ignores any other attributes |
`{ x, y } @ args: x + y` `args @ { x, y }: x + y` | A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args` |
*Built-in functions* | |
`import ./foo.nix` | Load and return Nix expression in given file |
`map (x: x + x) [ 1 2 3 ]` | Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`) |