Difference between revisions of "Overview of the Nix Language"

From NixOS Wiki
Jump to: navigation, search
m (Reverted edits by Zyansheep (talk) to last revision by Maintenance script)
Tag: Rollback
 
(14 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{Expansion|Incomplete (for now just converting the Incomplete category to this template/flag}}
+
<blockquote>The Nix language is designed for conveniently creating and composing <i>derivations</i> – precise descriptions of how contents of existing files are used to derive new files. </blockquote>
 +
<cite>[https://nixos.org/manual/nix/stable/language/ Nix Reference Manual]</cite>
  
This [[:Category:Pedias|pedia]] article covers the syntax, semantics, typing, compilation, tooling and libraries of the Nix Expression Language.
+
{{Note|Check the [https://nixos.org/manual/nix/stable/language/ Nix Reference Manual on the Nix Language] for up-to-date documentation and [https://nix.dev/tutorials/nix-language Nix language basics] for a gentle introduction.}}
 
 
<blockquote>The Nix expression language is a pure, lazy, functional language. Purity means that operations in the language don't have side-effects (for instance, there is no variable assignment). Laziness means that arguments to functions are evaluated only when they are needed. Functional means that functions are “normal” values that can be passed around and manipulated in interesting ways. The language is not a full-featured, general purpose language. Its main job is to describe packages, compositions of packages, and the variability within packages.</blockquote>
 
<cite>From the [https://nixos.org/nix/manual/#ch-expression-language Nix manual]</cite>
 
 
 
The language was designed especially for the [[Nix Package Manager]].
 
 
 
== Language Paradigms ==
 
 
 
=== Lazy ===
 
 
 
Not all expressions in nixpkgs will be evaluated and instantiated as nix performs evaluation only when needed for a finished output. In the following example <code>abort</code> will never be triggered as the variable it belongs to is unused:
 
<syntaxHighlight lang=nix>
 
let
 
  a = abort "will never happen";
 
  b = "hello";
 
  c = "world";
 
in b + c
 
</syntaxHighlight>
 
 
 
=== Functional ===
 
Functional Programming is a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements.
 
 
 
See also: [https://en.wikipedia.org/wiki/Functional_programming]
 
 
 
=== Pure ===
 
 
 
A pure function is a function where the return value is only determined by its input values, without observable side effects. In Nix, all build operations try to be as pure as possible to achieve reproducible builds. This means that wherever you build the packages as few side effects as possible should have an impact onto the build.
 
 
 
== Language Features ==
 
This section describes the main language features of the nix expression language.
 
 
 
=== Expressions ===
 
 
 
When Nix tutorials talk about '''Nix Expressions''' they typically mean the definition of a function with multiple inputs which as a result in a derivation. However a Nix expression can be everything, from a simple string, to a function to a set of expressions.
 
 
 
=== Types ===
 
 
 
The nix language provides a number of basic types:
 
{| class="wikitable"
 
|-
 
! Type !! Description !! Example
 
|-
 
| Strings || Strings either start with <code>double quotes</code> or <code>double single quotes</code>. They also support antiquotation (templating). Leading spaces are stripped with double single quotes. || <code>"Say ${pkgs.hello.name}"</code>
 
Multiline String:
 
<syntaxHighlight lang="nix">''
 
  first line
 
  second line
 
''</SyntaxHighlight>
 
|-
 
| Integers || A whole number without fractional component. || <code>5</code>
 
|-
 
| Floating-point numbers || Decimal numbers. Precision is limited. || <code>1.2</code>
 
|-
 
| Path || Relative paths will become absolute when evaluated, paths must contain a slash. <code><nixpkgs/pkgs></code> is also possible and will resolve to the folder incl. subfolders in your NIX_PATH || <syntaxHighlight>./hello/world
 
> /abs/path/to/hello/world
 
</syntaxHighlight>
 
<syntaxHighlight><nixpkgs/lib>
 
> /path/to/your/nixpkgs/lib</syntaxHighlight>
 
|-
 
| URI || Uniform Resource Identifiers || <code><nowiki>http://example.org/foo.tar.bz2</nowiki></code>
 
|-
 
| Boolean ||  || <code>true</code>, <code>false</code>
 
|-
 
| Null || A representation of nothing. || <code>null</code>
 
|-
 
| Lists || Items are separated by space, not comma. Each item can be a value of any other type || <syntaxHighlight lang=nix>[ 1 ./example.bin { hello="world"; }] </syntaxHighlight>
 
|-
 
| Sets || Associative data structures. In other languages called <code>dicts</code>(Python),<code>objects</code>(JavaScript) <code>hashes</code>(Ruby) or <code>maps</code>(Java). Essentially a list of key-value pairs || <syntaxHighlight lang=nix>{ key1="value1";  key2="value2"; }</syntaxHighlight>
 
Access values through dot-notation:<syntaxHighlight lang=nix>{ hello="world"; }.hello
 
> "world"</syntaxHighlight>
 
|-
 
| Functions || See below. || <code>argument: function-body</code>
 
|}
 
A detailed description of all types can be found in [https://nixos.org/nix/manual/#ssec-values The Nix manual].
 
 
 
=== Functions ===
 
 
 
Functions are all unnamed (=lambda) functions with the following notation: <code>argument: nixExpression</code>, e.g. <code>x: x*x</code>.
 
 
 
If you want to give that function a name, you have to assign it to a name, e.g. <code>square = x: x*x</code>.
 
So, <code>f(x) = x*x</code> in math is <code>f = x: x*x</code> in Nix.
 
 
 
If you want to use that function and apply it to a value like <code>f(3)</code>, you leave out the parentheses and add a space.
 
So, <code>f(3)</code> in math, is <code>f 3</code> in Nix.
 
 
 
If you want multiple arguments, you can add arguments like this: <code>arg1: arg2: nixExpression</code>, e.g. <code>f = x: y: x*y</code>. Applying that function to multiple values is easy: <code>f(3,4)</code> in math, is <code>f 3 4</code> in Nix.
 
If you apply one argument <code>f 3</code>only, a partial function <code>y: 3*y</code>is returned.
 
 
 
==== Destructuring ====
 
 
 
In nix it happens that sets are given as arguments to functions. Say that we declare a function which returns the concatenation of attributes a and b of a set like:
 
<syntaxHighlight lang=nix>
 
concat_a_and_b =  set: set.a + set.b
 
concat_a_and_b { a="hello"; b="world"; }
 
"helloworld"
 
</syntaxHighlight>
 
 
 
It is then possible to destructure the argument <code>set</code> and pick out the attributes that we are interested in, in the function declaration, resulting in a tidier function:
 
 
 
<syntaxHighlight lang=nix>
 
concat_a_and_b = {a, b}: a + b
 
concat_a_and_b { a="hello "; b="world"; }
 
"hello world"
 
</syntaxHighlight>
 
==== Default argument ====
 
It is also possible to assign default values to be used in a function if the caller omits one, but only as part of a set.
 
 
 
<syntaxHighlight lang=nix>
 
add_a_b = { a ? 1, b ? 2 }: a + b
 
add_a_b {}
 
3
 
add_a_b {a=5;}
 
7
 
</syntaxHighlight>
 
 
 
==== Accepting unexpected attributes in argument set ====
 
If you want your function to still run without error if the user provides a set with more attributes than you expected it to have you can use the ellipses.
 
 
 
<syntaxHighlight lang=nix>
 
add_a_b = { a, b }: a + b
 
add_a_b { a=5; b=2; c=10; }
 
error: anonymous function at (string):1:2 called with unexpected argument 'c', at (string):1:1
 
add_a_b = { a, b, ... }: a + b
 
add_a_b { a=5; b=2; c=10; }
 
7
 
</syntaxHighlight>
 
 
 
You can also store away the arguments in a name of your chosing using the <code>@</code> pattern.
 
 
 
<syntaxHighlight lang=nix>
 
add_a_b = args@{ a, b, ... }: a + b + args.c
 
add_a_b { a=5; b=2; c=10; }
 
17
 
</syntaxHighlight>
 
 
 
 
 
=== Operators ===
 
 
 
Lower precedence means a stronger binding; i.e. this list is sorted from strongest to weakest binding, and in the case of equal precedence between two operators, the associativity decides the binding.
 
 
 
{| class="wikitable"
 
!width="6%"| Prec
 
!width="13%"| Abbreviation
 
!width="24%"| Example
 
!width="13%"| Assoc
 
!width="42%"| Description
 
|-
 
| 1
 
| SELECT
 
| <code>e . attrpath [or def]</code>
 
| none
 
| Select attribute denoted by the attribute path <code>attrpath</code> from set <code>e</code>. (An attribute path is a dot-separated list of attribute names.) If the attribute doesn’t exist, return <code>default</code> if provided, otherwise abort evaluation.
 
|-
 
| 2
 
| APP
 
| <code>e1 e2</code>
 
| left
 
| Call function <code>e1</code> with argument <code>e2</code>.
 
|-
 
| 3
 
| NEG
 
| <code>-e</code>
 
| none
 
| Numeric negation.
 
|-
 
| 4
 
| HAS_ATTR
 
| <code>e ? attrpath</code>
 
| none
 
| Test whether set <code>e</code> contains the attribute denoted by <code>attrpath</code>; return true or false.
 
|-
 
| 5
 
| CONCAT
 
| <code>e1 ++ e2</code>
 
| right
 
| List concatenation.
 
|-
 
| 6
 
| MUL
 
| <code>e1 * e2</code>
 
| left
 
| Numeric multiplication.
 
|-
 
| 6
 
| DIV
 
| <code>e1 / e2</code>
 
| left
 
| Numeric division.
 
|-
 
| 7
 
| ADD
 
| <code>e1 + e2</code>
 
| left
 
| Numeric addition, or string concatenation.
 
|-
 
| 7
 
| SUB
 
| <code>e1 - e2</code>
 
| left
 
| Numeric subtraction.
 
|-
 
| 8
 
| NOT
 
| <code>!e</code>
 
| left
 
| Boolean negation.
 
|-
 
| 9
 
| UPDATE
 
| <code>e1 // e2</code>
 
| right
 
| Return a set consisting of the attributes in <code>e1</code> and <code>e2</code> (with the latter taking precedence over the former in case of equally named attributes).
 
|-
 
| 10
 
| LT
 
| <code>e1 &lt; e2</code>
 
| left
 
| Less than.
 
|-
 
| 10
 
| LTE
 
| <code>e1 &lt;= e2</code>
 
| left
 
| Less than or equal.
 
|-
 
| 10
 
| GT
 
| <code>e1 &gt; e2</code>
 
| left
 
| Greater than.
 
|-
 
| 10
 
| GTE
 
| <code>e1 &gt;= e2</code>
 
| left
 
| Greater than or equal.
 
|-
 
| 11
 
| EQ
 
| <code>e1 == e2</code>
 
| none
 
| Equality.
 
|-
 
| 11
 
| NEQ
 
| <code>e1 != e2</code>
 
| none
 
| Inequality.
 
|-
 
| 12
 
| AND
 
| <code>e1 &amp;&amp; e2</code>
 
| left
 
| Logical AND.
 
|-
 
| 13
 
| OR
 
| <code><nowiki>e1 || e2</nowiki></code>
 
| left
 
| Logical OR.
 
|-
 
| 14
 
| IMPL
 
| <code>e1 -&gt; e2</code>
 
| none
 
| Logical implication (equivalent to <code><nowiki>!e1 || e2</nowiki></code>).
 
|}
 
 
 
Source: [https://gist.github.com/joepie91/c3c047f3406aea9ec65eebce2ffd449d Gist of joepie91]
 
 
 
=== Imports ===
 
 
 
<code>import</code> loads, parses and imports the nix expression stored in path. This keyword is essentially a builtin of nix but not a part of the language itself.
 
 
 
Usage:
 
<syntaxHighlight lang=nix>
 
  x = import <nixpkgs> {};
 
  y = trace x.pkgs.hello.name x;
 
</syntaxHighlight>
 
 
 
=== Notable constructs ===
 
 
 
Nix looks a lot like JSON with functions but also provides a number of very specialized constructs which can help you build clean and easy to read expressions. In this sub-chapter the most notable constructs will be shown by example:
 
 
 
==== <code>with</code> statement ====
 
The [https://nixos.org/manual/nix/stable/#idm140737321903120 <code>with</code> statement] introduces an attrset's value contents into the lexical scope of into the expression which follows. This means that it brings all keys within that set (that do not already exist in an outer scope) into scope in that expression. So, you don't need to use the dot notation.
 
 
 
Example:
 
 
 
<syntaxHighlight lang=nix>
 
let
 
  myattrset = { a = 1; b = 2; };
 
in
 
  with myattrset; "In this string we have access to ${toString a} and ${toString b}"
 
</syntaxHighlight>
 
 
 
returns:
 
 
 
<syntaxHighlight lang=nix>
 
"In this string we have access to 1 and 2"
 
</syntaxHighlight>
 
 
 
Note that (perhaps surprisingly) <code>with</code> '''does not shadow''' values from outer scope. For example:
 
 
 
<syntaxHighlight lang=nix>
 
let
 
  a = 333;
 
in
 
  with { a = 1; b = 2; }; "In this string we have access to ${toString a} and ${toString b}"
 
</syntaxHighlight>
 
 
 
returns:
 
 
 
<syntaxHighlight lang=nix>
 
"In this string we have access to 333 and 2"
 
</syntaxHighlight>
 
 
 
This is because <code>a</code> was already defined in the scope outside the use of <code>with</code>, and <code>with</code> does ''not'' override it. The outer value takes precedence. (It is suspected by the author of this wiki section that the reason for this non-shadowing logic is lexical code stability: In the common usages of <code>with</code> as shown below, the contents of attrsets given to the statement are often large, community-maintained, and frequently updated. If e.g. <code>let myValue = ...; with lib; doSomethingWith myValue</code> shadowed the outer <code>myValue</code> bindings, the people maintaining `lib` could accidentally break this code by adding <code>lib.myValue</code>.)
 
 
 
Common usages are:
 
 
 
'''On top of expressions''':
 
 
 
Look at the following lib set:
 
<syntaxHighlight lang=nix>
 
lib = {
 
  ...
 
  types={
 
    attrsOf = ...;
 
    listOf = ...;
 
    str = ...;
 
  };
 
  ...
 
}
 
</syntaxHighlight>
 
 
 
You will see the with statement a lot at the beginning of expression definition. Most of the time it is used to load the lib functions into the namespace for quick access.
 
<syntaxHighlight lang=nix>
 
{lib, ... }:
 
 
 
with lib;
 
{
 
  options = {
 
    networking.hosts = mkOption {
 
      type = with types; attrsOf ( listOf str);
 
      default = {};
 
    };
 
  };
 
  ... 
 
}
 
</syntaxHighlight>
 
instead of:
 
<syntaxHighlight lang=nix>
 
{lib, ... }:
 
{
 
  options = {
 
    networking.hosts = lib.mkOption {
 
      type = lib.types.attrsOf ( lib.types.listOf lib.types.str);
 
      default = {};
 
    };
 
  };
 
  ... 
 
}
 
</syntaxHighlight>
 
 
 
'''In package input definitions''':
 
<syntaxHighlight lang=nix>
 
{pkgs}:
 
{
 
  ...
 
  buildInputs = with pkgs; [ curl php coreutils procps ffmpeg ];
 
}
 
</syntaxHighlight>
 
Instead of :
 
<syntaxHighlight lang=nix>
 
{pkgs}:
 
{
 
  ...
 
  buildInputs = [ pkgs.curl pkgs.php pkgs.coreutils pkgs.procps pkgs.ffmpeg ];
 
}
 
</syntaxHighlight>
 
 
 
'''In the package meta tag''':
 
<syntaxHighlight lang=nix>
 
{lib, ...}:
 
{
 
  ...
 
  meta = with lib; {
 
    license = with licenses; [ lgp3 gpl3 ];
 
    maintainers = with maintainers; [ adisbladis lassulus ];
 
  };
 
}
 
</syntaxHighlight>
 
Instead of :
 
<syntaxHighlight lang=nix>
 
{lib, ...}:
 
{
 
  ...
 
  meta = {
 
    license = [ lib.licenses.lgp3 lib.licenses.gpl3 ];
 
    maintainers = [ lib.maintainers.adisbladis lib.maintainers.lassulus ];
 
  };
 
}
 
</syntaxHighlight>
 
 
 
'''In a default.nix of an external package''':
 
<syntaxHighlight lang=nix>
 
with import <nixpkgs> {};
 
stdenv.mkDerivation rec {
 
    name = "mytool-env";
 
    src = ./.;
 
    buildInputs = with pkgs;[
 
      python34
 
      python34Packages.docopt
 
    ];
 
 
 
    shellHook =''
 
      export HISTFILE=$PWD/histfile
 
    '' ;
 
}
 
</syntaxHighlight>
 
 
 
==== <code>let ... in</code> statement ====
 
 
 
With <code>let</code> you can define local variables which can also reference to self without the need of the <code>rec</code> construct. This feature is used inside expressions to prepare variables which become part of an output.
 
The usage of <code>let</code> is comparable to the [http://zvon.org/other/haskell/Outputsyntax/letQexpressions_reference.html Haskell let expression]
 
<syntaxHighlight lang=nix>
 
let
 
  a = 1;
 
  b = 2;
 
in  a + b
 
=> 3
 
</syntaxHighlight>
 
 
 
==== <code>inherit</code> statement ====
 
 
 
The <code>inherit</code> expression can be used to copy variables from the surrounding lexical scope. A typical use case is to declare the version or name of a derivation in the expression and reuse this parameter in the function to fetch the source.
 
 
 
This is a typical python package derivation as the fetchPypi function also requires <code>pname</code> and <code>version</code> as input:
 
<syntaxHighlight lang=nix>
 
buildPythonPackage rec {
 
  pname = "hello";
 
  version = "1.0";
 
  src = fetchPypi {
 
    inherit pname version;
 
  sha256 = "01ba..0";
 
  };
 
}
 
</syntaxHighlight>
 
 
 
==== <code>rec</code> statement ====
 
 
 
The <code>rec</code> expression turns a basic set into a set where self-referencing is possible. This can be used when the <code>let</code> expression would create too much clutter. It is often seen in package derivation descriptions.
 
 
 
Sample usage:
 
<syntaxHighlight lang=nix>
 
rec {
 
  x = y - 100;
 
  y = 123;
 
}.x
 
=> 23
 
</syntaxHighlight>
 
  
 
== See also ==
 
== See also ==
 
* [[Nix Expression Language: Learning resources|Learning resources]]
 
* [[Nix Expression Language: Learning resources|Learning resources]]
 
* [[Editor Modes for Nix Files]]
 
* [[Editor Modes for Nix Files]]
* [[Nix Expression Language: Tips & Tricks]]
+
* [[Nix Language: Tips & Tricks]]
 
* [[Nix Language Quirks]]
 
* [[Nix Language Quirks]]
  
 
[[Category:Pedias]]
 
[[Category:Pedias]]
[[Category:Nix Expression Language]]
+
[[Category:Nix Language]]

Latest revision as of 10:44, 13 April 2024

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.

Nix Reference Manual

Note: Check the Nix Reference Manual on the Nix Language for up-to-date documentation and Nix language basics for a gentle introduction.

See also