aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/src/expressions
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-07-22 23:17:48 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-07-23 18:26:48 +0200
commitef606760abd87c98371fbc08c1f25ad897823a2a (patch)
treea1f5c77f1302c7cf3b2b1a8945b175d8cde77c66 /doc/manual/src/expressions
parentd004715665046ff424f267deccccb78c9d5cabb7 (diff)
Pandoc conversion
Diffstat (limited to 'doc/manual/src/expressions')
-rw-r--r--doc/manual/src/expressions/advanced-attributes.md233
-rw-r--r--doc/manual/src/expressions/arguments-variables.md72
-rw-r--r--doc/manual/src/expressions/build-script.md72
-rw-r--r--doc/manual/src/expressions/builder-syntax.md72
-rw-r--r--doc/manual/src/expressions/builtins.md839
-rw-r--r--doc/manual/src/expressions/derivations.md154
-rw-r--r--doc/manual/src/expressions/expression-language.md12
-rw-r--r--doc/manual/src/expressions/expression-syntax.md91
-rw-r--r--doc/manual/src/expressions/generic-builder.md61
-rw-r--r--doc/manual/src/expressions/language-constructs.md291
-rw-r--r--doc/manual/src/expressions/language-operators.md32
-rw-r--r--doc/manual/src/expressions/language-values.md209
-rw-r--r--doc/manual/src/expressions/simple-building-testing.md57
-rw-r--r--doc/manual/src/expressions/simple-expression.md27
-rw-r--r--doc/manual/src/expressions/writing-nix-expressions.md12
15 files changed, 2234 insertions, 0 deletions
diff --git a/doc/manual/src/expressions/advanced-attributes.md b/doc/manual/src/expressions/advanced-attributes.md
new file mode 100644
index 000000000..683b504a7
--- /dev/null
+++ b/doc/manual/src/expressions/advanced-attributes.md
@@ -0,0 +1,233 @@
+# Advanced Attributes
+
+Derivations can declare some infrequently used optional attributes.
+
+ - `allowedReferences`
+ The optional attribute `allowedReferences` specifies a list of legal
+ references (dependencies) of the output of the builder. For example,
+
+ allowedReferences = [];
+
+ enforces that the output of a derivation cannot have any runtime
+ dependencies on its inputs. To allow an output to have a runtime
+ dependency on itself, use `"out"` as a list item. This is used in
+ NixOS to check that generated files such as initial ramdisks for
+ booting Linux don’t have accidental dependencies on other paths in
+ the Nix store.
+
+ - `allowedRequisites`
+ This attribute is similar to `allowedReferences`, but it specifies
+ the legal requisites of the whole closure, so all the dependencies
+ recursively. For example,
+
+ allowedRequisites = [ foobar ];
+
+ enforces that the output of a derivation cannot have any other
+ runtime dependency than `foobar`, and in addition it enforces that
+ `foobar` itself doesn't introduce any other dependency itself.
+
+ - `disallowedReferences`
+ The optional attribute `disallowedReferences` specifies a list of
+ illegal references (dependencies) of the output of the builder. For
+ example,
+
+ disallowedReferences = [ foo ];
+
+ enforces that the output of a derivation cannot have a direct
+ runtime dependencies on the derivation `foo`.
+
+ - `disallowedRequisites`
+ This attribute is similar to `disallowedReferences`, but it
+ specifies illegal requisites for the whole closure, so all the
+ dependencies recursively. For example,
+
+ disallowedRequisites = [ foobar ];
+
+ enforces that the output of a derivation cannot have any runtime
+ dependency on `foobar` or any other derivation depending recursively
+ on `foobar`.
+
+ - `exportReferencesGraph`
+ This attribute allows builders access to the references graph of
+ their inputs. The attribute is a list of inputs in the Nix store
+ whose references graph the builder needs to know. The value of this
+ attribute should be a list of pairs `[ name1
+ path1 name2
+ path2 ...
+ ]`. The references graph of each pathN will be stored in a text file
+ nameN in the temporary build directory. The text files have the
+ format used by `nix-store
+ --register-validity` (with the deriver fields left empty). For
+ example, when the following derivation is built:
+
+ derivation {
+ ...
+ exportReferencesGraph = [ "libfoo-graph" libfoo ];
+ };
+
+ the references graph of `libfoo` is placed in the file
+ `libfoo-graph` in the temporary build directory.
+
+ `exportReferencesGraph` is useful for builders that want to do
+ something with the closure of a store path. Examples include the
+ builders in NixOS that generate the initial ramdisk for booting
+ Linux (a `cpio` archive containing the closure of the boot script)
+ and the ISO-9660 image for the installation CD (which is populated
+ with a Nix store containing the closure of a bootable NixOS
+ configuration).
+
+ - `impureEnvVars`
+ This attribute allows you to specify a list of environment variables
+ that should be passed from the environment of the calling user to
+ the builder. Usually, the environment is cleared completely when the
+ builder is executed, but with this attribute you can allow specific
+ environment variables to be passed unmodified. For example,
+ `fetchurl` in Nixpkgs has the line
+
+ impureEnvVars = [ "http_proxy" "https_proxy" ... ];
+
+ to make it use the proxy server configuration specified by the user
+ in the environment variables http\_proxy and friends.
+
+ This attribute is only allowed in [fixed-output
+ derivations](#fixed-output-drvs), where impurities such as these are
+ okay since (the hash of) the output is known in advance. It is
+ ignored for all other derivations.
+
+ > **Warning**
+ >
+ > `impureEnvVars` implementation takes environment variables from
+ > the current builder process. When a daemon is building its
+ > environmental variables are used. Without the daemon, the
+ > environmental variables come from the environment of the
+ > `nix-build`.
+
+ - `outputHash`; `outputHashAlgo`; `outputHashMode`
+ These attributes declare that the derivation is a so-called
+ *fixed-output derivation*, which means that a cryptographic hash of
+ the output is already known in advance. When the build of a
+ fixed-output derivation finishes, Nix computes the cryptographic
+ hash of the output and compares it to the hash declared with these
+ attributes. If there is a mismatch, the build fails.
+
+ The rationale for fixed-output derivations is derivations such as
+ those produced by the `fetchurl` function. This function downloads a
+ file from a given URL. To ensure that the downloaded file has not
+ been modified, the caller must also specify a cryptographic hash of
+ the file. For example,
+
+ fetchurl {
+ url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ }
+
+ It sometimes happens that the URL of the file changes, e.g., because
+ servers are reorganised or no longer available. We then must update
+ the call to `fetchurl`, e.g.,
+
+ fetchurl {
+ url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ }
+
+ If a `fetchurl` derivation was treated like a normal derivation, the
+ output paths of the derivation and *all derivations depending on it*
+ would change. For instance, if we were to change the URL of the
+ Glibc source distribution in Nixpkgs (a package on which almost all
+ other packages depend) massive rebuilds would be needed. This is
+ unfortunate for a change which we know cannot have a real effect as
+ it propagates upwards through the dependency graph.
+
+ For fixed-output derivations, on the other hand, the name of the
+ output path only depends on the `outputHash*` and `name` attributes,
+ while all other attributes are ignored for the purpose of computing
+ the output path. (The `name` attribute is included because it is
+ part of the path.)
+
+ As an example, here is the (simplified) Nix expression for
+ `fetchurl`:
+
+ { stdenv, curl }: # The curl program is used for downloading.
+
+ { url, sha256 }:
+
+ stdenv.mkDerivation {
+ name = baseNameOf (toString url);
+ builder = ./builder.sh;
+ buildInputs = [ curl ];
+
+ # This is a fixed-output derivation; the output must be a regular
+ # file with SHA256 hash sha256.
+ outputHashMode = "flat";
+ outputHashAlgo = "sha256";
+ outputHash = sha256;
+
+ inherit url;
+ }
+
+ The `outputHashAlgo` attribute specifies the hash algorithm used to
+ compute the hash. It can currently be `"sha1"`, `"sha256"` or
+ `"sha512"`.
+
+ The `outputHashMode` attribute determines how the hash is computed.
+ It must be one of the following two values:
+
+ - `"flat"`
+ The output must be a non-executable regular file. If it isn’t,
+ the build fails. The hash is simply computed over the contents
+ of that file (so it’s equal to what Unix commands like
+ `sha256sum` or `sha1sum` produce).
+
+ This is the default.
+
+ - `"recursive"`
+ The hash is computed over the NAR archive dump of the output
+ (i.e., the result of [`nix-store
+ --dump`](#refsec-nix-store-dump)). In this case, the output can
+ be anything, including a directory tree.
+
+ The `outputHash` attribute, finally, must be a string containing the
+ hash in either hexadecimal or base-32 notation. (See the [`nix-hash`
+ command](#sec-nix-hash) for information about converting to and from
+ base-32 notation.)
+
+ - `passAsFile`
+ A list of names of attributes that should be passed via files rather
+ than environment variables. For example, if you have
+
+ ```
+ passAsFile = ["big"];
+ big = "a very long string";
+
+ ```
+
+ then when the builder runs, the environment variable bigPath will
+ contain the absolute path to a temporary file containing `a very
+ long
+ string`. That is, for any attribute x listed in `passAsFile`, Nix
+ will pass an environment variable xPath holding the path of the file
+ containing the value of attribute x. This is useful when you need to
+ pass large strings to a builder, since most operating systems impose
+ a limit on the size of the environment (typically, a few hundred
+ kilobyte).
+
+ - `preferLocalBuild`
+ If this attribute is set to `true` and [distributed building is
+ enabled](#chap-distributed-builds), then, if possible, the derivaton
+ will be built locally instead of forwarded to a remote machine. This
+ is appropriate for trivial builders where the cost of doing a
+ download or remote build would exceed the cost of building locally.
+
+ - `allowSubstitutes`
+ If this attribute is set to `false`, then Nix will always build this
+ derivation; it will not try to substitute its outputs. This is
+ useful for very trivial derivations (such as `writeText` in Nixpkgs)
+ that are cheaper to build than to substitute from a binary cache.
+
+ > **Note**
+ >
+ > You need to have a builder configured which satisfies the
+ > derivation’s `system` attribute, since the derivation cannot be
+ > substituted. Thus it is usually a good idea to align `system` with
+ > `builtins.currentSystem` when setting `allowSubstitutes` to
+ > `false`. For most trivial derivations this should be the case.
diff --git a/doc/manual/src/expressions/arguments-variables.md b/doc/manual/src/expressions/arguments-variables.md
new file mode 100644
index 000000000..9a373d94d
--- /dev/null
+++ b/doc/manual/src/expressions/arguments-variables.md
@@ -0,0 +1,72 @@
+# Arguments and Variables
+
+ ...
+
+ rec {
+
+ hello = import ../applications/misc/hello/ex-1 {
+ inherit fetchurl stdenv perl;
+ };
+
+ perl = import ../development/interpreters/perl {
+ inherit fetchurl stdenv;
+ };
+
+ fetchurl = import ../build-support/fetchurl {
+ inherit stdenv; ...
+ };
+
+ stdenv = ...;
+
+ }
+
+The Nix expression in [???](#ex-hello-nix) is a function; it is missing
+some arguments that have to be filled in somewhere. In the Nix Packages
+collection this is done in the file `pkgs/top-level/all-packages.nix`,
+where all Nix expressions for packages are imported and called with the
+appropriate arguments. [example\_title](#ex-hello-composition) shows
+some fragments of `all-packages.nix`.
+
+ - This file defines a set of attributes, all of which are concrete
+ derivations (i.e., not functions). In fact, we define a *mutually
+ recursive* set of attributes. That is, the attributes can refer to
+ each other. This is precisely what we want since we want to “plug”
+ the various packages into each other.
+
+ - Here we *import* the Nix expression for GNU Hello. The import
+ operation just loads and returns the specified Nix expression. In
+ fact, we could just have put the contents of [???](#ex-hello-nix) in
+ `all-packages.nix` at this point. That would be completely
+ equivalent, but it would make the file rather bulky.
+
+ Note that we refer to `../applications/misc/hello/ex-1`, not
+ `../applications/misc/hello/ex-1/default.nix`. When you try to
+ import a directory, Nix automatically appends `/default.nix` to the
+ file name.
+
+ - This is where the actual composition takes place. Here we *call* the
+ function imported from `../applications/misc/hello/ex-1` with a set
+ containing the things that the function expects, namely `fetchurl`,
+ `stdenv`, and `perl`. We use inherit again to use the attributes
+ defined in the surrounding scope (we could also have written
+ `fetchurl = fetchurl;`, etc.).
+
+ The result of this function call is an actual derivation that can be
+ built by Nix (since when we fill in the arguments of the function,
+ what we get is its body, which is the call to `stdenv.mkDerivation`
+ in [???](#ex-hello-nix)).
+
+ > **Note**
+ >
+ > Nixpkgs has a convenience function `callPackage` that imports and
+ > calls a function, filling in any missing arguments by passing the
+ > corresponding attribute from the Nixpkgs set, like this:
+ >
+ > hello = callPackage ../applications/misc/hello/ex-1 { };
+ >
+ > If necessary, you can set or override arguments:
+ >
+ > hello = callPackage ../applications/misc/hello/ex-1 { stdenv = myStdenv; };
+
+ - Likewise, we have to instantiate Perl, `fetchurl`, and the standard
+ environment.
diff --git a/doc/manual/src/expressions/build-script.md b/doc/manual/src/expressions/build-script.md
new file mode 100644
index 000000000..256a5cd44
--- /dev/null
+++ b/doc/manual/src/expressions/build-script.md
@@ -0,0 +1,72 @@
+# Build Script
+
+ source $stdenv/setup
+
+ PATH=$perl/bin:$PATH
+
+ tar xvfz $src
+ cd hello-*
+ ./configure --prefix=$out
+ make
+ make install
+
+[example\_title](#ex-hello-builder) shows the builder referenced from
+Hello's Nix expression (stored in
+`pkgs/applications/misc/hello/ex-1/builder.sh`). The builder can
+actually be made a lot shorter by using the *generic builder* functions
+provided by `stdenv`, but here we write out the build steps to elucidate
+what a builder does. It performs the following steps:
+
+ - When Nix runs a builder, it initially completely clears the
+ environment (except for the attributes declared in the derivation).
+ For instance, the PATH variable is empty\[1\]. This is done to
+ prevent undeclared inputs from being used in the build process. If
+ for example the PATH contained `/usr/bin`, then you might
+ accidentally use `/usr/bin/gcc`.
+
+ So the first step is to set up the environment. This is done by
+ calling the `setup` script of the standard environment. The
+ environment variable stdenv points to the location of the standard
+ environment being used. (It wasn't specified explicitly as an
+ attribute in [???](#ex-hello-nix), but `mkDerivation` adds it
+ automatically.)
+
+ - Since Hello needs Perl, we have to make sure that Perl is in the
+ PATH. The perl environment variable points to the location of the
+ Perl package (since it was passed in as an attribute to the
+ derivation), so `$perl/bin` is the directory containing the Perl
+ interpreter.
+
+ - Now we have to unpack the sources. The `src` attribute was bound to
+ the result of fetching the Hello source tarball from the network, so
+ the src environment variable points to the location in the Nix store
+ to which the tarball was downloaded. After unpacking, we `cd` to the
+ resulting source directory.
+
+ The whole build is performed in a temporary directory created in
+ `/tmp`, by the way. This directory is removed after the builder
+ finishes, so there is no need to clean up the sources afterwards.
+ Also, the temporary directory is always newly created, so you don't
+ have to worry about files from previous builds interfering with the
+ current build.
+
+ - GNU Hello is a typical Autoconf-based package, so we first have to
+ run its `configure` script. In Nix every package is stored in a
+ separate location in the Nix store, for instance
+ `/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1`. Nix
+ computes this path by cryptographically hashing all attributes of
+ the derivation. The path is passed to the builder through the out
+ environment variable. So here we give `configure` the parameter
+ `--prefix=$out` to cause Hello to be installed in the expected
+ location.
+
+ - Finally we build Hello (`make`) and install it into the location
+ specified by out (`make install`).
+
+If you are wondering about the absence of error checking on the result
+of various commands called in the builder: this is because the shell
+script is evaluated with Bash's `-e` option, which causes the script to
+be aborted if any command fails without an error check.
+
+1. Actually, it's initialised to `/path-not-set` to prevent Bash from
+ setting it to a default value.
diff --git a/doc/manual/src/expressions/builder-syntax.md b/doc/manual/src/expressions/builder-syntax.md
new file mode 100644
index 000000000..c92acf106
--- /dev/null
+++ b/doc/manual/src/expressions/builder-syntax.md
@@ -0,0 +1,72 @@
+# Builder Syntax
+
+ source $stdenv/setup
+
+ PATH=$perl/bin:$PATH
+
+ tar xvfz $src
+ cd hello-*
+ ./configure --prefix=$out
+ make
+ make install
+
+[example\_title](#ex-hello-builder) shows the builder referenced from
+Hello's Nix expression (stored in
+`pkgs/applications/misc/hello/ex-1/builder.sh`). The builder can
+actually be made a lot shorter by using the *generic builder* functions
+provided by `stdenv`, but here we write out the build steps to elucidate
+what a builder does. It performs the following steps:
+
+ - When Nix runs a builder, it initially completely clears the
+ environment (except for the attributes declared in the derivation).
+ For instance, the PATH variable is empty\[1\]. This is done to
+ prevent undeclared inputs from being used in the build process. If
+ for example the PATH contained `/usr/bin`, then you might
+ accidentally use `/usr/bin/gcc`.
+
+ So the first step is to set up the environment. This is done by
+ calling the `setup` script of the standard environment. The
+ environment variable stdenv points to the location of the standard
+ environment being used. (It wasn't specified explicitly as an
+ attribute in [???](#ex-hello-nix), but `mkDerivation` adds it
+ automatically.)
+
+ - Since Hello needs Perl, we have to make sure that Perl is in the
+ PATH. The perl environment variable points to the location of the
+ Perl package (since it was passed in as an attribute to the
+ derivation), so `$perl/bin` is the directory containing the Perl
+ interpreter.
+
+ - Now we have to unpack the sources. The `src` attribute was bound to
+ the result of fetching the Hello source tarball from the network, so
+ the src environment variable points to the location in the Nix store
+ to which the tarball was downloaded. After unpacking, we `cd` to the
+ resulting source directory.
+
+ The whole build is performed in a temporary directory created in
+ `/tmp`, by the way. This directory is removed after the builder
+ finishes, so there is no need to clean up the sources afterwards.
+ Also, the temporary directory is always newly created, so you don't
+ have to worry about files from previous builds interfering with the
+ current build.
+
+ - GNU Hello is a typical Autoconf-based package, so we first have to
+ run its `configure` script. In Nix every package is stored in a
+ separate location in the Nix store, for instance
+ `/nix/store/9a54ba97fb71b65fda531012d0443ce2-hello-2.1.1`. Nix
+ computes this path by cryptographically hashing all attributes of
+ the derivation. The path is passed to the builder through the out
+ environment variable. So here we give `configure` the parameter
+ `--prefix=$out` to cause Hello to be installed in the expected
+ location.
+
+ - Finally we build Hello (`make`) and install it into the location
+ specified by out (`make install`).
+
+If you are wondering about the absence of error checking on the result
+of various commands called in the builder: this is because the shell
+script is evaluated with Bash's `-e` option, which causes the script to
+be aborted if any command fails without an error check.
+
+1. Actually, it's initialised to `/path-not-set` to prevent Bash from
+ setting it to a default value.
diff --git a/doc/manual/src/expressions/builtins.md b/doc/manual/src/expressions/builtins.md
new file mode 100644
index 000000000..a378fe8e4
--- /dev/null
+++ b/doc/manual/src/expressions/builtins.md
@@ -0,0 +1,839 @@
+# Built-in Functions
+
+This section lists the functions and constants built into the Nix
+expression evaluator. (The built-in function `derivation` is discussed
+above.) Some built-ins, such as `derivation`, are always in scope of
+every Nix expression; you can just access them right away. But to
+prevent polluting the namespace too much, most built-ins are not in
+scope. Instead, you can access them through the `builtins` built-in
+value, which is a set that contains all built-in functions and values.
+For instance, `derivation` is also available as `builtins.derivation`.
+
+ - `abort` s; `builtins.abort` s
+ Abort Nix expression evaluation, print error message s.
+
+ - `builtins.add` e1 e2
+ Return the sum of the numbers e1 and e2.
+
+ - `builtins.all` pred list
+ Return `true` if the function pred returns `true` for all elements
+ of list, and `false` otherwise.
+
+ - `builtins.any` pred list
+ Return `true` if the function pred returns `true` for at least one
+ element of list, and `false` otherwise.
+
+ - `builtins.attrNames` set
+ Return the names of the attributes in the set set in an
+ alphabetically sorted list. For instance, `builtins.attrNames { y
+ = 1; x = "foo"; }` evaluates to `[ "x" "y" ]`.
+
+ - `builtins.attrValues` set
+ Return the values of the attributes in the set set in the order
+ corresponding to the sorted attribute names.
+
+ - `baseNameOf` s
+ Return the *base name* of the string s, that is, everything
+ following the final slash in the string. This is similar to the GNU
+ `basename` command.
+
+ - `builtins.bitAnd` e1 e2
+ Return the bitwise AND of the integers e1 and e2.
+
+ - `builtins.bitOr` e1 e2
+ Return the bitwise OR of the integers e1 and e2.
+
+ - `builtins.bitXor` e1 e2
+ Return the bitwise XOR of the integers e1 and e2.
+
+ - `builtins`
+ The set `builtins` contains all the built-in functions and values.
+ You can use `builtins` to test for the availability of features in
+ the Nix installation, e.g.,
+
+ if builtins ? getEnv then builtins.getEnv "PATH" else ""
+
+ This allows a Nix expression to fall back gracefully on older Nix
+ installations that don’t have the desired built-in function.
+
+ - `builtins.compareVersions` s1 s2
+ Compare two strings representing versions and return `-1` if version
+ s1 is older than version s2, `0` if they are the same, and `1` if s1
+ is newer than s2. The version comparison algorithm is the same as
+ the one used by [`nix-env
+ -u`](#ssec-version-comparisons).
+
+ - `builtins.concatLists` lists
+ Concatenate a list of lists into a single list.
+
+ - `builtins.concatStringsSep` separator list
+ Concatenate a list of strings with a separator between each element,
+ e.g. `concatStringsSep "/"
+ ["usr" "local" "bin"] == "usr/local/bin"`
+
+ - `builtins.currentSystem`
+ The built-in value `currentSystem` evaluates to the Nix platform
+ identifier for the Nix installation on which the expression is being
+ evaluated, such as `"i686-linux"` or `"x86_64-darwin"`.
+
+ - `builtins.deepSeq` e1 e2
+ This is like `seq
+ e1
+ e2`, except that e1 is evaluated *deeply*: if it’s a list or set,
+ its elements or attributes are also evaluated recursively.
+
+ - `derivation` attrs; `builtins.derivation` attrs
+ `derivation` is described in [???](#ssec-derivation).
+
+ - `dirOf` s; `builtins.dirOf` s
+ Return the directory part of the string s, that is, everything
+ before the final slash in the string. This is similar to the GNU
+ `dirname` command.
+
+ - `builtins.div` e1 e2
+ Return the quotient of the numbers e1 and e2.
+
+ - `builtins.elem` x xs
+ Return `true` if a value equal to x occurs in the list xs, and
+ `false` otherwise.
+
+ - `builtins.elemAt` xs n
+ Return element n from the list xs. Elements are counted starting
+ from 0. A fatal error occurs if the index is out of bounds.
+
+ - `builtins.fetchurl` url
+ Download the specified URL and return the path of the downloaded
+ file. This function is not available if [restricted evaluation
+ mode](#conf-restrict-eval) is enabled.
+
+ - `fetchTarball` url; `builtins.fetchTarball` url
+ Download the specified URL, unpack it and return the path of the
+ unpacked tree. The file must be a tape archive (`.tar`) compressed
+ with `gzip`, `bzip2` or `xz`. The top-level path component of the
+ files in the tarball is removed, so it is best if the tarball
+ contains a single directory at top level. The typical use of the
+ function is to obtain external Nix expression dependencies, such as
+ a particular version of Nixpkgs, e.g.
+
+ with import (fetchTarball https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz) {};
+
+ stdenv.mkDerivation { … }
+
+ The fetched tarball is cached for a certain amount of time (1 hour
+ by default) in `~/.cache/nix/tarballs/`. You can change the cache
+ timeout either on the command line with `--option tarball-ttl number
+ of seconds` or in the Nix configuration file with this option: `
+ number of seconds to cache `.
+
+ Note that when obtaining the hash with ` nix-prefetch-url
+ ` the option `--unpack` is required.
+
+ This function can also verify the contents against a hash. In that
+ case, the function takes a set instead of a URL. The set requires
+ the attribute `url` and the attribute `sha256`, e.g.
+
+ with import (fetchTarball {
+ url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz";
+ sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2";
+ }) {};
+
+ stdenv.mkDerivation { … }
+
+ This function is not available if [restricted evaluation
+ mode](#conf-restrict-eval) is enabled.
+
+ - `builtins.fetchGit` args
+ Fetch a path from git. args can be a URL, in which case the HEAD of
+ the repo at that URL is fetched. Otherwise, it can be an attribute
+ with the following attributes (all except `url` optional):
+
+ - url
+ The URL of the repo.
+
+ - name
+ The name of the directory the repo should be exported to in the
+ store. Defaults to the basename of the URL.
+
+ - rev
+ The git revision to fetch. Defaults to the tip of `ref`.
+
+ - ref
+ The git ref to look for the requested revision under. This is
+ often a branch or tag name. Defaults to `HEAD`.
+
+ By default, the `ref` value is prefixed with `refs/heads/`. As
+ of Nix 2.3.0 Nix will not prefix `refs/heads/` if `ref` starts
+ with `refs/`.
+
+ - submodules
+ A Boolean parameter that specifies whether submodules should be
+ checked out. Defaults to `false`.
+
+ <!-- end list -->
+
+ builtins.fetchGit {
+ url = "git@github.com:my-secret/repository.git";
+ ref = "master";
+ rev = "adab8b916a45068c044658c4158d81878f9ed1c3";
+ }
+
+ builtins.fetchGit {
+ url = "https://github.com/NixOS/nix.git";
+ ref = "refs/heads/0.5-release";
+ }
+
+ If the revision you're looking for is in the default branch of the
+ git repository you don't strictly need to specify the branch name in
+ the `ref` attribute.
+
+ However, if the revision you're looking for is in a future branch
+ for the non-default branch you will need to specify the the `ref`
+ attribute as well.
+
+ builtins.fetchGit {
+ url = "https://github.com/nixos/nix.git";
+ rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452";
+ ref = "1.11-maintenance";
+ }
+
+ > **Note**
+ >
+ > It is nice to always specify the branch which a revision belongs
+ > to. Without the branch being specified, the fetcher might fail if
+ > the default branch changes. Additionally, it can be confusing to
+ > try a commit from a non-default branch and see the fetch fail. If
+ > the branch is specified the fault is much more obvious.
+
+ If the revision you're looking for is in the default branch of the
+ git repository you may omit the `ref` attribute.
+
+ builtins.fetchGit {
+ url = "https://github.com/nixos/nix.git";
+ rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452";
+ }
+
+ builtins.fetchGit {
+ url = "https://github.com/nixos/nix.git";
+ ref = "refs/tags/1.9";
+ }
+
+ `builtins.fetchGit` can behave impurely fetch the latest version of
+ a remote branch.
+
+ > **Note**
+ >
+ > Nix will refetch the branch in accordance to
+ > [???](#conf-tarball-ttl).
+
+ > **Note**
+ >
+ > This behavior is disabled in *Pure evaluation mode*.
+
+ builtins.fetchGit {
+ url = "ssh://git@github.com/nixos/nix.git";
+ ref = "master";
+ }
+
+ - `builtins.filter` f xs
+ Return a list consisting of the elements of xs for which the
+ function f returns `true`.
+
+ - `builtins.filterSource` e1 e2
+ This function allows you to copy sources into the Nix store while
+ filtering certain files. For instance, suppose that you want to use
+ the directory `source-dir` as an input to a Nix expression, e.g.
+
+ stdenv.mkDerivation {
+ ...
+ src = ./source-dir;
+ }
+
+ However, if `source-dir` is a Subversion working copy, then all
+ those annoying `.svn` subdirectories will also be copied to the
+ store. Worse, the contents of those directories may change a lot,
+ causing lots of spurious rebuilds. With `filterSource` you can
+ filter out the `.svn` directories:
+
+ ```
+ src = builtins.filterSource
+ (path: type: type != "directory" || baseNameOf path != ".svn")
+ ./source-dir;
+ ```
+
+ Thus, the first argument e1 must be a predicate function that is
+ called for each regular file, directory or symlink in the source
+ tree e2. If the function returns `true`, the file is copied to the
+ Nix store, otherwise it is omitted. The function is called with two
+ arguments. The first is the full path of the file. The second is a
+ string that identifies the type of the file, which is either
+ `"regular"`, `"directory"`, `"symlink"` or `"unknown"` (for other
+ kinds of files such as device nodes or fifos — but note that those
+ cannot be copied to the Nix store, so if the predicate returns
+ `true` for them, the copy will fail). If you exclude a directory,
+ the entire corresponding subtree of e2 will be excluded.
+
+ - `builtins.foldl’` op nul list
+ Reduce a list by applying a binary operator, from left to right,
+ e.g. `foldl’ op nul [x0 x1 x2 ...] = op (op
+ (op nul x0) x1) x2) ...`. The operator is applied strictly, i.e.,
+ its arguments are evaluated first. For example, `foldl’ (x: y: x +
+ y) 0 [1 2 3]` evaluates to 6.
+
+ - `builtins.functionArgs` f
+ Return a set containing the names of the formal arguments expected
+ by the function f. The value of each attribute is a Boolean denoting
+ whether the corresponding argument has a default value. For
+ instance, `functionArgs ({ x, y ? 123}: ...) = { x = false; y =
+ true; }`.
+
+ "Formal argument" here refers to the attributes pattern-matched by
+ the function. Plain lambdas are not included, e.g. `functionArgs (x:
+ ...) = { }`.
+
+ - `builtins.fromJSON` e
+ Convert a JSON string to a Nix value. For example,
+
+ builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
+
+ returns the value `{ x = [ 1 2 3 ]; y = null;
+ }`.
+
+ - `builtins.genList` generator length
+ Generate list of size length, with each element i equal to the value
+ returned by generator `i`. For example,
+
+ builtins.genList (x: x * x) 5
+
+ returns the list `[ 0 1 4 9 16 ]`.
+
+ - `builtins.getAttr` s set
+ `getAttr` returns the attribute named s from set. Evaluation aborts
+ if the attribute doesn’t exist. This is a dynamic version of the `.`
+ operator, since s is an expression rather than an identifier.
+
+ - `builtins.getEnv` s
+ `getEnv` returns the value of the environment variable s, or an
+ empty string if the variable doesn’t exist. This function should be
+ used with care, as it can introduce all sorts of nasty environment
+ dependencies in your Nix expression.
+
+ `getEnv` is used in Nix Packages to locate the file
+ `~/.nixpkgs/config.nix`, which contains user-local settings for Nix
+ Packages. (That is, it does a `getEnv "HOME"` to locate the user’s
+ home directory.)
+
+ - `builtins.hasAttr` s set
+ `hasAttr` returns `true` if set has an attribute named s, and
+ `false` otherwise. This is a dynamic version of the `?` operator,
+ since s is an expression rather than an identifier.
+
+ - `builtins.hashString` type s
+ Return a base-16 representation of the cryptographic hash of string
+ s. The hash algorithm specified by type must be one of `"md5"`,
+ `"sha1"`, `"sha256"` or `"sha512"`.
+
+ - `builtins.hashFile` type p
+ Return a base-16 representation of the cryptographic hash of the
+ file at path p. The hash algorithm specified by type must be one of
+ `"md5"`, `"sha1"`, `"sha256"` or `"sha512"`.
+
+ - `builtins.head` list
+ Return the first element of a list; abort evaluation if the argument
+ isn’t a list or is an empty list. You can test whether a list is
+ empty by comparing it with `[]`.
+
+ - `import` path; `builtins.import` path
+ Load, parse and return the Nix expression in the file path. If path
+ is a directory, the file ` default.nix
+ ` in that directory is loaded. Evaluation aborts if the file
+ doesn’t exist or contains an incorrect Nix expression. `import`
+ implements Nix’s module system: you can put any Nix expression (such
+ as a set or a function) in a separate file, and use it from Nix
+ expressions in other files.
+
+ > **Note**
+ >
+ > Unlike some languages, `import` is a regular function in Nix.
+ > Paths using the angle bracket syntax (e.g., `
+ > > > > > import` \<foo\>) are normal path values (see [???](#ssec-values)).
+
+ A Nix expression loaded by `import` must not contain any *free
+ variables* (identifiers that are not defined in the Nix expression
+ itself and are not built-in). Therefore, it cannot refer to
+ variables that are in scope at the call site. For instance, if you
+ have a calling expression
+
+ rec {
+ x = 123;
+ y = import ./foo.nix;
+ }
+
+ then the following `foo.nix` will give an error:
+
+ x + 456
+
+ since `x` is not in scope in `foo.nix`. If you want `x` to be
+ available in `foo.nix`, you should pass it as a function argument:
+
+ rec {
+ x = 123;
+ y = import ./foo.nix x;
+ }
+
+ and
+
+ x: x + 456
+
+ (The function argument doesn’t have to be called `x` in `foo.nix`;
+ any name would work.)
+
+ - `builtins.intersectAttrs` e1 e2
+ Return a set consisting of the attributes in the set e2 that also
+ exist in the set e1.
+
+ - `builtins.isAttrs` e
+ Return `true` if e evaluates to a set, and `false` otherwise.
+
+ - `builtins.isList` e
+ Return `true` if e evaluates to a list, and `false` otherwise.
+
+ - `builtins.isFunction` e
+ Return `true` if e evaluates to a function, and `false` otherwise.
+
+ - `builtins.isString` e
+ Return `true` if e evaluates to a string, and `false` otherwise.
+
+ - `builtins.isInt` e
+ Return `true` if e evaluates to an int, and `false` otherwise.
+
+ - `builtins.isFloat` e
+ Return `true` if e evaluates to a float, and `false` otherwise.
+
+ - `builtins.isBool` e
+ Return `true` if e evaluates to a bool, and `false` otherwise.
+
+ - `builtins.isPath` e
+ Return `true` if e evaluates to a path, and `false` otherwise.
+
+ - `isNull` e; `builtins.isNull` e
+ Return `true` if e evaluates to `null`, and `false` otherwise.
+
+ > **Warning**
+ >
+ > This function is *deprecated*; just write `e == null` instead.
+
+ - `builtins.length` e
+ Return the length of the list e.
+
+ - `builtins.lessThan` e1 e2
+ Return `true` if the number e1 is less than the number e2, and
+ `false` otherwise. Evaluation aborts if either e1 or e2 does not
+ evaluate to a number.
+
+ - `builtins.listToAttrs` e
+ Construct a set from a list specifying the names and values of each
+ attribute. Each element of the list should be a set consisting of a
+ string-valued attribute `name` specifying the name of the attribute,
+ and an attribute `value` specifying its value. Example:
+
+ builtins.listToAttrs
+ [ { name = "foo"; value = 123; }
+ { name = "bar"; value = 456; }
+ ]
+
+ evaluates to
+
+ { foo = 123; bar = 456; }
+
+ - `map` f list; `builtins.map` f list
+ Apply the function f to each element in the list list. For example,
+
+ map (x: "foo" + x) [ "bar" "bla" "abc" ]
+
+ evaluates to `[ "foobar" "foobla" "fooabc"
+ ]`.
+
+ - `builtins.match` regex str
+ Returns a list if the [extended POSIX regular
+ expression](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04)
+ regex matches str precisely, otherwise returns `null`. Each item in
+ the list is a regex group.
+
+ builtins.match "ab" "abc"
+
+ Evaluates to `null`.
+
+ builtins.match "abc" "abc"
+
+ Evaluates to `[ ]`.
+
+ builtins.match "a(b)(c)" "abc"
+
+ Evaluates to `[ "b" "c" ]`.
+
+ builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO "
+
+ Evaluates to `[ "foo" ]`.
+
+ - `builtins.mul` e1 e2
+ Return the product of the numbers e1 and e2.
+
+ - `builtins.parseDrvName` s
+ Split the string s into a package name and version. The package name
+ is everything up to but not including the first dash followed by a
+ digit, and the version is everything following that dash. The result
+ is returned in a set `{ name, version }`. Thus,
+ `builtins.parseDrvName "nix-0.12pre12876"` returns `{ name = "nix";
+ version = "0.12pre12876";
+ }`.
+
+ - `builtins.path` args
+ An enrichment of the built-in path type, based on the attributes
+ present in args. All are optional except `path`:
+
+ - path
+ The underlying path.
+
+ - name
+ The name of the path when added to the store. This can used to
+ reference paths that have nix-illegal characters in their names,
+ like `@`.
+
+ - filter
+ A function of the type expected by
+ [builtins.filterSource](#builtin-filterSource), with the same
+ semantics.
+
+ - recursive
+ When `false`, when `path` is added to the store it is with a
+ flat hash, rather than a hash of the NAR serialization of the
+ file. Thus, `path` must refer to a regular file, not a
+ directory. This allows similar behavior to `fetchurl`. Defaults
+ to `true`.
+
+ - sha256
+ When provided, this is the expected hash of the file at the
+ path. Evaluation will fail if the hash is incorrect, and
+ providing a hash allows `builtins.path` to be used even when the
+ `pure-eval` nix config option is on.
+
+ - `builtins.pathExists` path
+ Return `true` if the path path exists at evaluation time, and
+ `false` otherwise.
+
+ - `builtins.placeholder` output
+ Return a placeholder string for the specified output that will be
+ substituted by the corresponding output path at build time. Typical
+ outputs would be `"out"`, `"bin"` or `"dev"`.
+
+ - `builtins.readDir` path
+ Return the contents of the directory path as a set mapping directory
+ entries to the corresponding file type. For instance, if directory
+ `A` contains a regular file `B` and another directory `C`, then
+ `builtins.readDir
+ ./A` will return the set
+
+ { B = "regular"; C = "directory"; }
+
+ The possible values for the file type are `"regular"`,
+ `"directory"`, `"symlink"` and `"unknown"`.
+
+ - `builtins.readFile` path
+ Return the contents of the file path as a string.
+
+ - `removeAttrs` set list; `builtins.removeAttrs` set list
+ Remove the attributes listed in list from set. The attributes don’t
+ have to exist in set. For instance,
+
+ removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ]
+
+ evaluates to `{ y = 2; }`.
+
+ - `builtins.replaceStrings` from to s
+ Given string s, replace every occurrence of the strings in from with
+ the corresponding string in to. For example,
+
+ builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar"
+
+ evaluates to `"fabir"`.
+
+ - `builtins.seq` e1 e2
+ Evaluate e1, then evaluate and return e2. This ensures that a
+ computation is strict in the value of e1.
+
+ - `builtins.sort` comparator list
+ Return list in sorted order. It repeatedly calls the function
+ comparator with two elements. The comparator should return `true` if
+ the first element is less than the second, and `false` otherwise.
+ For example,
+
+ builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
+
+ produces the list `[ 42 77 147 249 483 526
+ ]`.
+
+ This is a stable sort: it preserves the relative order of elements
+ deemed equal by the comparator.
+
+ - `builtins.split` regex str
+ Returns a list composed of non matched strings interleaved with the
+ lists of the [extended POSIX regular
+ expression](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04)
+ regex matches of str. Each item in the lists of matched sequences is
+ a regex group.
+
+ builtins.split "(a)b" "abc"
+
+ Evaluates to `[ "" [ "a" ] "c" ]`.
+
+ builtins.split "([ac])" "abc"
+
+ Evaluates to `[ "" [ "a" ] "b" [ "c" ] "" ]`.
+
+ builtins.split "(a)|(c)" "abc"
+
+ Evaluates to `[ "" [ "a" null ] "b" [ null "c" ] "" ]`.
+
+ builtins.split "([[:upper:]]+)" " FOO "
+
+ Evaluates to `[ " " [ "FOO" ] " " ]`.
+
+ - `builtins.splitVersion` s
+ Split a string representing a version into its components, by the
+ same version splitting logic underlying the version comparison in
+ [`nix-env -u`](#ssec-version-comparisons).
+
+ - `builtins.stringLength` e
+ Return the length of the string e. If e is not a string, evaluation
+ is aborted.
+
+ - `builtins.sub` e1 e2
+ Return the difference between the numbers e1 and e2.
+
+ - `builtins.substring` start len s
+ Return the substring of s from character position start (zero-based)
+ up to but not including start + len. If start is greater than the
+ length of the string, an empty string is returned, and if start +
+ len lies beyond the end of the string, only the substring up to the
+ end of the string is returned. start must be non-negative. For
+ example,
+
+ builtins.substring 0 3 "nixos"
+
+ evaluates to `"nix"`.
+
+ - `builtins.tail` list
+ Return the second to last elements of a list; abort evaluation if
+ the argument isn’t a list or is an empty list.
+
+ - `throw` s; `builtins.throw` s
+ Throw an error message s. This usually aborts Nix expression
+ evaluation, but in `nix-env -qa` and other commands that try to
+ evaluate a set of derivations to get information about those
+ derivations, a derivation that throws an error is silently skipped
+ (which is not the case for `abort`).
+
+ - `builtins.toFile` name s
+ Store the string s in a file in the Nix store and return its path.
+ The file has suffix name. This file can be used as an input to
+ derivations. One application is to write builders “inline”. For
+ instance, the following Nix expression combines [???](#ex-hello-nix)
+ and [???](#ex-hello-builder) into one file:
+
+ { stdenv, fetchurl, perl }:
+
+ stdenv.mkDerivation {
+ name = "hello-2.1.1";
+
+ builder = builtins.toFile "builder.sh" "
+ source $stdenv/setup
+
+ PATH=$perl/bin:$PATH
+
+ tar xvfz $src
+ cd hello-*
+ ./configure --prefix=$out
+ make
+ make install
+ ";
+
+ src = fetchurl {
+ url = "http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ };
+ inherit perl;
+ }
+
+ It is even possible for one file to refer to another, e.g.,
+
+ ```
+ builder = let
+ configFile = builtins.toFile "foo.conf" "
+ # This is some dummy configuration file.
+ ...
+ ";
+ in builtins.toFile "builder.sh" "
+ source $stdenv/setup
+ ...
+ cp ${configFile} $out/etc/foo.conf
+ ";
+ ```
+
+ Note that `${configFile}` is an antiquotation (see
+ [???](#ssec-values)), so the result of the expression `configFile`
+ (i.e., a path like `/nix/store/m7p7jfny445k...-foo.conf`) will be
+ spliced into the resulting string.
+
+ It is however *not* allowed to have files mutually referring to each
+ other, like so:
+
+ let
+ foo = builtins.toFile "foo" "...${bar}...";
+ bar = builtins.toFile "bar" "...${foo}...";
+ in foo
+
+ This is not allowed because it would cause a cyclic dependency in
+ the computation of the cryptographic hashes for `foo` and `bar`.
+
+ It is also not possible to reference the result of a derivation. If
+ you are using Nixpkgs, the `writeTextFile` function is able to do
+ that.
+
+ - `builtins.toJSON` e
+ Return a string containing a JSON representation of e. Strings,
+ integers, floats, booleans, nulls and lists are mapped to their JSON
+ equivalents. Sets (except derivations) are represented as objects.
+ Derivations are translated to a JSON string containing the
+ derivation’s output path. Paths are copied to the store and
+ represented as a JSON string of the resulting store path.
+
+ - `builtins.toPath` s
+ DEPRECATED. Use `/. + "/path"` to convert a string into an absolute
+ path. For relative paths, use `./. + "/path"`.
+
+ - `toString` e; `builtins.toString` e
+ Convert the expression e to a string. e can be:
+
+ - A string (in which case the string is returned unmodified).
+
+ - A path (e.g., `toString /foo/bar` yields `"/foo/bar"`.
+
+ - A set containing `{ __toString = self: ...; }`.
+
+ - An integer.
+
+ - A list, in which case the string representations of its elements
+ are joined with spaces.
+
+ - A Boolean (`false` yields `""`, `true` yields `"1"`).
+
+ - `null`, which yields the empty string.
+
+ - `builtins.toXML` e
+ Return a string containing an XML representation of e. The main
+ application for `toXML` is to communicate information with the
+ builder in a more structured format than plain environment
+ variables.
+
+ [example\_title](#ex-toxml) shows an example where this is the case.
+ The builder is supposed to generate the configuration file for a
+ [Jetty servlet container](http://jetty.mortbay.org/). A servlet
+ container contains a number of servlets (`*.war` files) each
+ exported under a specific URI prefix. So the servlet configuration
+ is a list of sets containing the `path` and `war` of the servlet
+ ([co\_title](#ex-toxml-co-servlets)). This kind of information is
+ difficult to communicate with the normal method of passing
+ information through an environment variable, which just concatenates
+ everything together into a string (which might just work in this
+ case, but wouldn’t work if fields are optional or contain lists
+ themselves). Instead the Nix expression is converted to an XML
+ representation with `toXML`, which is unambiguous and can easily be
+ processed with the appropriate tools. For instance, in the example
+ an XSLT stylesheet ([co\_title](#ex-toxml-co-stylesheet)) is applied
+ to it ([co\_title](#ex-toxml-co-apply)) to generate the XML
+ configuration file for the Jetty server. The XML representation
+ produced from [co\_title](#ex-toxml-co-servlets) by `toXML` is shown
+ in [example\_title](#ex-toxml-result).
+
+ Note that [example\_title](#ex-toxml) uses the `toFile` built-in to
+ write the builder and the stylesheet “inline” in the Nix expression.
+ The path of the stylesheet is spliced into the builder at `xsltproc
+ ${stylesheet}
+ ...`.
+
+ { stdenv, fetchurl, libxslt, jira, uberwiki }:
+
+ stdenv.mkDerivation (rec {
+ name = "web-server";
+
+ buildInputs = [ libxslt ];
+
+ builder = builtins.toFile "builder.sh" "
+ source $stdenv/setup
+ mkdir $out
+ echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml
+ ";
+
+ stylesheet = builtins.toFile "stylesheet.xsl"
+ "<?xml version='1.0' encoding='UTF-8'?>
+ <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
+ <xsl:template match='/'>
+ <Configure>
+ <xsl:for-each select='/expr/list/attrs'>
+ <Call name='addWebApplication'>
+ <Arg><xsl:value-of select=\"attr[@name = 'path']/string/@value\" /></Arg>
+ <Arg><xsl:value-of select=\"attr[@name = 'war']/path/@value\" /></Arg>
+ </Call>
+ </xsl:for-each>
+ </Configure>
+ </xsl:template>
+ </xsl:stylesheet>
+ ";
+
+ servlets = builtins.toXML [
+ { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
+ { path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
+ ];
+ })
+
+ <?xml version='1.0' encoding='utf-8'?>
+ <expr>
+ <list>
+ <attrs>
+ <attr name="path">
+ <string value="/bugtracker" />
+ </attr>
+ <attr name="war">
+ <path value="/nix/store/d1jh9pasa7k2...-jira/lib/atlassian-jira.war" />
+ </attr>
+ </attrs>
+ <attrs>
+ <attr name="path">
+ <string value="/wiki" />
+ </attr>
+ <attr name="war">
+ <path value="/nix/store/y6423b1yi4sx...-uberwiki/uberwiki.war" />
+ </attr>
+ </attrs>
+ </list>
+ </expr>
+
+ - `builtins.trace` e1 e2
+ Evaluate e1 and print its abstract syntax representation on standard
+ error. Then return e2. This function is useful for debugging.
+
+ - `builtins.tryEval` e
+ Try to shallowly evaluate e. Return a set containing the attributes
+ `success` (`true` if e evaluated successfully, `false` if an error
+ was thrown) and `value`, equalling e if successful and `false`
+ otherwise. Note that this doesn't evaluate e deeply, so ` let e = {
+ x = throw ""; }; in (builtins.tryEval e).success
+ ` will be `true`. Using ` builtins.deepSeq
+ ` one can get the expected result: `let e = { x = throw "";
+ }; in (builtins.tryEval (builtins.deepSeq e e)).success` will be
+ `false`.
+
+ - `builtins.typeOf` e
+ Return a string representing the type of the value e, namely
+ `"int"`, `"bool"`, `"string"`, `"path"`, `"null"`, `"set"`,
+ `"list"`, `"lambda"` or `"float"`.
diff --git a/doc/manual/src/expressions/derivations.md b/doc/manual/src/expressions/derivations.md
new file mode 100644
index 000000000..7ffc6fabe
--- /dev/null
+++ b/doc/manual/src/expressions/derivations.md
@@ -0,0 +1,154 @@
+# Derivations
+
+The most important built-in function is `derivation`, which is used to
+describe a single derivation (a build action). It takes as input a set,
+the attributes of which specify the inputs of the build.
+
+ - There must be an attribute named `system` whose value must be a
+ string specifying a Nix platform identifier, such as `"i686-linux"`
+ or `"x86_64-darwin"`\[1\] The build can only be performed on a
+ machine and operating system matching the platform identifier. (Nix
+ can automatically forward builds for other platforms by forwarding
+ them to other machines; see [???](#chap-distributed-builds).)
+
+ - There must be an attribute named `name` whose value must be a
+ string. This is used as a symbolic name for the package by
+ `nix-env`, and it is appended to the output paths of the derivation.
+
+ - There must be an attribute named `builder` that identifies the
+ program that is executed to perform the build. It can be either a
+ derivation or a source (a local file reference, e.g.,
+ `./builder.sh`).
+
+ - Every attribute is passed as an environment variable to the builder.
+ Attribute values are translated to environment variables as follows:
+
+ - Strings and numbers are just passed verbatim.
+
+ - A *path* (e.g., `../foo/sources.tar`) causes the referenced file
+ to be copied to the store; its location in the store is put in
+ the environment variable. The idea is that all sources should
+ reside in the Nix store, since all inputs to a derivation should
+ reside in the Nix store.
+
+ - A *derivation* causes that derivation to be built prior to the
+ present derivation; its default output path is put in the
+ environment variable.
+
+ - Lists of the previous types are also allowed. They are simply
+ concatenated, separated by spaces.
+
+ - `true` is passed as the string `1`, `false` and `null` are
+ passed as an empty string.
+
+ - The optional attribute `args` specifies command-line arguments to be
+ passed to the builder. It should be a list.
+
+ - The optional attribute `outputs` specifies a list of symbolic
+ outputs of the derivation. By default, a derivation produces a
+ single output path, denoted as `out`. However, derivations can
+ produce multiple output paths. This is useful because it allows
+ outputs to be downloaded or garbage-collected separately. For
+ instance, imagine a library package that provides a dynamic library,
+ header files, and documentation. A program that links against the
+ library doesn’t need the header files and documentation at runtime,
+ and it doesn’t need the documentation at build time. Thus, the
+ library package could specify:
+
+ outputs = [ "lib" "headers" "doc" ];
+
+ This will cause Nix to pass environment variables `lib`, `headers`
+ and `doc` to the builder containing the intended store paths of each
+ output. The builder would typically do something like
+
+ ./configure --libdir=$lib/lib --includedir=$headers/include --docdir=$doc/share/doc
+
+ for an Autoconf-style package. You can refer to each output of a
+ derivation by selecting it as an attribute, e.g.
+
+ buildInputs = [ pkg.lib pkg.headers ];
+
+ The first element of `outputs` determines the *default output*.
+ Thus, you could also write
+
+ buildInputs = [ pkg pkg.headers ];
+
+ since `pkg` is equivalent to `pkg.lib`.
+
+The function `mkDerivation` in the Nixpkgs standard environment is a
+wrapper around `derivation` that adds a default value for `system` and
+always uses Bash as the builder, to which the supplied builder is passed
+as a command-line argument. See the Nixpkgs manual for details.
+
+The builder is executed as follows:
+
+ - A temporary directory is created under the directory specified by
+ TMPDIR (default `/tmp`) where the build will take place. The current
+ directory is changed to this directory.
+
+ - The environment is cleared and set to the derivation attributes, as
+ specified above.
+
+ - In addition, the following variables are set:
+
+ - NIX\_BUILD\_TOP contains the path of the temporary directory for
+ this build.
+
+ - Also, TMPDIR, TEMPDIR, TMP, TEMP are set to point to the
+ temporary directory. This is to prevent the builder from
+ accidentally writing temporary files anywhere else. Doing so
+ might cause interference by other processes.
+
+ - PATH is set to `/path-not-set` to prevent shells from
+ initialising it to their built-in default value.
+
+ - HOME is set to `/homeless-shelter` to prevent programs from
+ using `/etc/passwd` or the like to find the user's home
+ directory, which could cause impurity. Usually, when HOME is
+ set, it is used as the location of the home directory, even if
+ it points to a non-existent path.
+
+ - NIX\_STORE is set to the path of the top-level Nix store
+ directory (typically, `/nix/store`).
+
+ - For each output declared in `outputs`, the corresponding
+ environment variable is set to point to the intended path in the
+ Nix store for that output. Each output path is a concatenation
+ of the cryptographic hash of all build inputs, the `name`
+ attribute and the output name. (The output name is omitted if
+ it’s `out`.)
+
+ - If an output path already exists, it is removed. Also, locks are
+ acquired to prevent multiple Nix instances from performing the same
+ build at the same time.
+
+ - A log of the combined standard output and error is written to
+ `/nix/var/log/nix`.
+
+ - The builder is executed with the arguments specified by the
+ attribute `args`. If it exits with exit code 0, it is considered to
+ have succeeded.
+
+ - The temporary directory is removed (unless the `-K` option was
+ specified).
+
+ - If the build was successful, Nix scans each output path for
+ references to input paths by looking for the hash parts of the input
+ paths. Since these are potential runtime dependencies, Nix registers
+ them as dependencies of the output paths.
+
+ - After the build, Nix sets the last-modified timestamp on all files
+ in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to
+ the default group, and sets the mode of the file to 0444 or 0555
+ (i.e., read-only, with execute permission enabled if the file was
+ originally executable). Note that possible `setuid` and `setgid`
+ bits are cleared. Setuid and setgid programs are not currently
+ supported by Nix. This is because the Nix archives used in
+ deployment have no concept of ownership information, and because it
+ makes the build result dependent on the user performing the build.
+
+<!-- end list -->
+
+1. To figure out your platform identifier, look at the line “Checking
+ for the canonical Nix system name” in the output of Nix's
+ `configure` script.
diff --git a/doc/manual/src/expressions/expression-language.md b/doc/manual/src/expressions/expression-language.md
new file mode 100644
index 000000000..267fcb983
--- /dev/null
+++ b/doc/manual/src/expressions/expression-language.md
@@ -0,0 +1,12 @@
+# Nix Expression Language
+
+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.
+
+This section presents the various features of the language.
diff --git a/doc/manual/src/expressions/expression-syntax.md b/doc/manual/src/expressions/expression-syntax.md
new file mode 100644
index 000000000..935484c33
--- /dev/null
+++ b/doc/manual/src/expressions/expression-syntax.md
@@ -0,0 +1,91 @@
+# Expression Syntax
+
+ { stdenv, fetchurl, perl }:
+
+ stdenv.mkDerivation {
+ name = "hello-2.1.1";
+ builder = ./builder.sh;
+ src = fetchurl {
+ url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
+ sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
+ };
+ inherit perl;
+ }
+
+[example\_title](#ex-hello-nix) shows a Nix expression for GNU Hello.
+It's actually already in the Nix Packages collection in
+`pkgs/applications/misc/hello/ex-1/default.nix`. It is customary to
+place each package in a separate directory and call the single Nix
+expression in that directory `default.nix`. The file has the following
+elements (referenced from the figure by number):
+
+ - This states that the expression is a *function* that expects to be
+ called with three arguments: `stdenv`, `fetchurl`, and `perl`. They
+ are needed to build Hello, but we don't know how to build them here;
+ that's why they are function arguments. `stdenv` is a package that
+ is used by almost all Nix Packages packages; it provides a
+ “standard” environment consisting of the things you would expect
+ in a basic Unix environment: a C/C++ compiler (GCC, to be precise),
+ the Bash shell, fundamental Unix tools such as `cp`, `grep`, `tar`,
+ etc. `fetchurl` is a function that downloads files. `perl` is the
+ Perl interpreter.
+
+ Nix functions generally have the form `{ x, y, ...,
+ z }: e` where `x`, `y`, etc. are the names of the expected
+ arguments, and where e is the body of the function. So here, the
+ entire remainder of the file is the body of the function; when given
+ the required arguments, the body should describe how to build an
+ instance of the Hello package.
+
+ - So we have to build a package. Building something from other stuff
+ is called a *derivation* in Nix (as opposed to sources, which are
+ built by humans instead of computers). We perform a derivation by
+ calling `stdenv.mkDerivation`. `mkDerivation` is a function provided
+ by `stdenv` that builds a package from a set of *attributes*. A set
+ is just a list of key/value pairs where each key is a string and
+ each value is an arbitrary Nix expression. They take the general
+ form `{
+ name1 =
+ expr1; ...
+ nameN =
+ exprN; }`.
+
+ - The attribute `name` specifies the symbolic name and version of the
+ package. Nix doesn't really care about these things, but they are
+ used by for instance `nix-env
+ -q` to show a “human-readable” name for packages. This attribute is
+ required by `mkDerivation`.
+
+ - The attribute `builder` specifies the builder. This attribute can
+ sometimes be omitted, in which case `mkDerivation` will fill in a
+ default builder (which does a `configure; make; make install`, in
+ essence). Hello is sufficiently simple that the default builder
+ would suffice, but in this case, we will show an actual builder for
+ educational purposes. The value `./builder.sh` refers to the shell
+ script shown in [???](#ex-hello-builder), discussed below.
+
+ - The builder has to know what the sources of the package are. Here,
+ the attribute `src` is bound to the result of a call to the
+ `fetchurl` function. Given a URL and a SHA-256 hash of the expected
+ contents of the file at that URL, this function builds a derivation
+ that downloads the file and checks its hash. So the sources are a
+ dependency that like all other dependencies is built before Hello
+ itself is built.
+
+ Instead of `src` any other name could have been used, and in fact
+ there can be any number of sources (bound to different attributes).
+ However, `src` is customary, and it's also expected by the default
+ builder (which we don't use in this example).
+
+ - Since the derivation requires Perl, we have to pass the value of the
+ `perl` function argument to the builder. All attributes in the set
+ are actually passed as environment variables to the builder, so
+ declaring an attribute
+
+ perl = perl;
+
+ will do the trick: it binds an attribute `perl` to the function
+ argument which also happens to be called `perl`. However, it looks a
+ bit silly, so there is a shorter syntax. The `inherit` keyword
+ causes the specified attributes to be bound to whatever variables
+ with the same name happen to be in scope.
diff --git a/doc/manual/src/expressions/generic-builder.md b/doc/manual/src/expressions/generic-builder.md
new file mode 100644
index 000000000..cbc484199
--- /dev/null
+++ b/doc/manual/src/expressions/generic-builder.md
@@ -0,0 +1,61 @@
+# Generic Builder Syntax
+
+Recall from [???](#ex-hello-builder) that the builder looked something
+like this:
+
+ PATH=$perl/bin:$PATH
+ tar xvfz $src
+ cd hello-*
+ ./configure --prefix=$out
+ make
+ make install
+
+The builders for almost all Unix packages look like this — set up some
+environment variables, unpack the sources, configure, build, and
+install. For this reason the standard environment provides some Bash
+functions that automate the build process. A builder using the generic
+build facilities in shown in [example\_title](#ex-hello-builder2).
+
+ buildInputs="$perl"
+
+ source $stdenv/setup
+
+ genericBuild
+
+ - The buildInputs variable tells `setup` to use the indicated packages
+ as “inputs”. This means that if a package provides a `bin`
+ subdirectory, it's added to PATH; if it has a `include`
+ subdirectory, it's added to GCC's header search path; and so
+ on.\[1\]
+
+ - The function `genericBuild` is defined in the file `$stdenv/setup`.
+
+ - The final step calls the shell function `genericBuild`, which
+ performs the steps that were done explicitly in
+ [???](#ex-hello-builder). The generic builder is smart enough to
+ figure out whether to unpack the sources using `gzip`, `bzip2`, etc.
+ It can be customised in many ways; see the Nixpkgs manual for
+ details.
+
+Discerning readers will note that the buildInputs could just as well
+have been set in the Nix expression, like this:
+
+```
+ buildInputs = [ perl ];
+```
+
+The `perl` attribute can then be removed, and the builder becomes even
+shorter:
+
+ source $stdenv/setup
+ genericBuild
+
+In fact, `mkDerivation` provides a default builder that looks exactly
+like that, so it is actually possible to omit the builder for Hello
+entirely.
+
+1. How does it work? `setup` tries to source the file
+ `pkg/nix-support/setup-hook` of all dependencies. These “setup
+ hooks” can then set up whatever environment variables they want;
+ for instance, the setup hook for Perl sets the PERL5LIB environment
+ variable to contain the `lib/site_perl` directories of all inputs.
diff --git a/doc/manual/src/expressions/language-constructs.md b/doc/manual/src/expressions/language-constructs.md
new file mode 100644
index 000000000..a773c239b
--- /dev/null
+++ b/doc/manual/src/expressions/language-constructs.md
@@ -0,0 +1,291 @@
+# Language Constructs
+
+Recursive sets are just normal sets, but the attributes can refer to
+each other. For example,
+
+ rec {
+ x = y;
+ y = 123;
+ }.x
+
+evaluates to `123`. Note that without `rec` the binding `x = y;` would
+refer to the variable `y` in the surrounding scope, if one exists, and
+would be invalid if no such variable exists. That is, in a normal
+(non-recursive) set, attributes are not added to the lexical scope; in a
+recursive set, they are.
+
+Recursive sets of course introduce the danger of infinite recursion. For
+example,
+
+ rec {
+ x = y;
+ y = x;
+ }.x
+
+does not terminate\[1\].
+
+A let-expression allows you to define local variables for an expression.
+For instance,
+
+ let
+ x = "foo";
+ y = "bar";
+ in x + y
+
+evaluates to `"foobar"`.
+
+When defining a set or in a let-expression it is often convenient to
+copy variables from the surrounding lexical scope (e.g., when you want
+to propagate attributes). This can be shortened using the `inherit`
+keyword. For instance,
+
+ let x = 123; in
+ { inherit x;
+ y = 456;
+ }
+
+is equivalent to
+
+ let x = 123; in
+ { x = x;
+ y = 456;
+ }
+
+and both evaluate to `{ x = 123; y = 456; }`. (Note that this works
+because `x` is added to the lexical scope by the `let` construct.) It is
+also possible to inherit attributes from another set. For instance, in
+this fragment from `all-packages.nix`,
+
+```
+ graphviz = (import ../tools/graphics/graphviz) {
+ inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
+ inherit (xlibs) libXaw;
+ };
+
+ xlibs = {
+ libX11 = ...;
+ libXaw = ...;
+ ...
+ }
+
+ libpng = ...;
+ libjpg = ...;
+ ...
+```
+
+the set used in the function call to the function defined in
+`../tools/graphics/graphviz` inherits a number of variables from the
+surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
+(the X Athena Widgets) from the `xlibs` (X11 client-side libraries) set.
+
+Summarizing the fragment
+
+ ...
+ inherit x y z;
+ inherit (src-set) a b c;
+ ...
+
+is equivalent to
+
+ ...
+ x = x; y = y; z = z;
+ a = src-set.a; b = src-set.b; c = src-set.c;
+ ...
+
+when used while defining local variables in a let-expression or while
+defining a set.
+
+Functions have the following form:
+
+ pattern: body
+
+The pattern specifies what the argument of the function must look like,
+and binds variables in the body to (parts of) the argument. There are
+three kinds of patterns:
+
+ - If a pattern is a single identifier, then the function matches any
+ argument. Example:
+
+ let negate = x: !x;
+ concat = x: y: x + y;
+ in if negate true then concat "foo" "bar" else ""
+
+ Note that `concat` is a function that takes one argument and returns
+ a function that takes another argument. This allows partial
+ parameterisation (i.e., only filling some of the arguments of a
+ function); e.g.,
+
+ map (concat "foo") [ "bar" "bla" "abc" ]
+
+ evaluates to `[ "foobar" "foobla"
+ "fooabc" ]`.
+
+ - A *set pattern* of the form `{ name1, name2, …, nameN }` matches a
+ set containing the listed attributes, and binds the values of those
+ attributes to variables in the function body. For example, the
+ function
+
+ { x, y, z }: z + y + x
+
+ can only be called with a set containing exactly the attributes `x`,
+ `y` and `z`. No other attributes are allowed. If you want to allow
+ additional arguments, you can use an ellipsis (`...`):
+
+ { x, y, z, ... }: z + y + x
+
+ This works on any set that contains at least the three named
+ attributes.
+
+ It is possible to provide *default values* for attributes, in which
+ case they are allowed to be missing. A default value is specified by
+ writing `name ?
+ e`, where e is an arbitrary expression. For example,
+
+ { x, y ? "foo", z ? "bar" }: z + y + x
+
+ specifies a function that only requires an attribute named `x`, but
+ optionally accepts `y` and `z`.
+
+ - An `@`-pattern provides a means of referring to the whole value
+ being matched:
+
+ ```
+ args@{ x, y, z, ... }: z + y + x + args.a
+ ```
+
+ but can also be written as:
+
+ ```
+ { x, y, z, ... } @ args: z + y + x + args.a
+ ```
+
+ Here `args` is bound to the entire argument, which is further
+ matched against the pattern `{ x, y, z,
+ ... }`. `@`-pattern makes mainly sense with an ellipsis(`...`) as
+ you can access attribute names as `a`, using `args.a`, which was
+ given as an additional attribute to the function.
+
+ > **Warning**
+ >
+ > The `args@` expression is bound to the argument passed to the
+ > function which means that attributes with defaults that aren't
+ > explicitly specified in the function call won't cause an
+ > evaluation error, but won't exist in `args`.
+ >
+ > For instance
+ >
+ > let
+ > function = args@{ a ? 23, ... }: args;
+ > in
+ > function {}
+ >
+ > will evaluate to an empty attribute set.
+
+Note that functions do not have names. If you want to give them a name,
+you can bind them to an attribute, e.g.,
+
+ let concat = { x, y }: x + y;
+ in concat { x = "foo"; y = "bar"; }
+
+Conditionals look like this:
+
+ if e1 then e2 else e3
+
+where e1 is an expression that should evaluate to a Boolean value
+(`true` or `false`).
+
+Assertions are generally used to check that certain requirements on or
+between features and dependencies hold. They look like this:
+
+ assert e1; e2
+
+where e1 is an expression that should evaluate to a Boolean value. If it
+evaluates to `true`, e2 is returned; otherwise expression evaluation is
+aborted and a backtrace is printed.
+
+ { localServer ? false
+ , httpServer ? false
+ , sslSupport ? false
+ , pythonBindings ? false
+ , javaSwigBindings ? false
+ , javahlBindings ? false
+ , stdenv, fetchurl
+ , openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
+ }:
+
+ assert localServer -> db4 != null;
+ assert httpServer -> httpd != null && httpd.expat == expat;
+ assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);
+ assert pythonBindings -> swig != null && swig.pythonSupport;
+ assert javaSwigBindings -> swig != null && swig.javaSupport;
+ assert javahlBindings -> j2sdk != null;
+
+ stdenv.mkDerivation {
+ name = "subversion-1.1.1";
+ ...
+ openssl = if sslSupport then openssl else null;
+ ...
+ }
+
+[example\_title](#ex-subversion-nix) show how assertions are used in the
+Nix expression for Subversion.
+
+ - This assertion states that if Subversion is to have support for
+ local repositories, then Berkeley DB is needed. So if the Subversion
+ function is called with the `localServer` argument set to `true` but
+ the `db4` argument set to `null`, then the evaluation fails.
+
+ - This is a more subtle condition: if Subversion is built with Apache
+ (`httpServer`) support, then the Expat library (an XML library) used
+ by Subversion should be same as the one used by Apache. This is
+ because in this configuration Subversion code ends up being linked
+ with Apache code, and if the Expat libraries do not match, a build-
+ or runtime link error or incompatibility might occur.
+
+ - This assertion says that in order for Subversion to have SSL support
+ (so that it can access `https` URLs), an OpenSSL library must be
+ passed. Additionally, it says that *if* Apache support is enabled,
+ then Apache's OpenSSL should match Subversion's. (Note that if
+ Apache support is not enabled, we don't care about Apache's
+ OpenSSL.)
+
+ - The conditional here is not really related to assertions, but is
+ worth pointing out: it ensures that if SSL support is disabled, then
+ the Subversion derivation is not dependent on OpenSSL, even if a
+ non-`null` value was passed. This prevents an unnecessary rebuild of
+ Subversion if OpenSSL changes.
+
+A *with-expression*,
+
+ with e1; e2
+
+introduces the set e1 into the lexical scope of the expression e2. For
+instance,
+
+ let as = { x = "foo"; y = "bar"; };
+ in with as; x + y
+
+evaluates to `"foobar"` since the `with` adds the `x` and `y` attributes
+of `as` to the lexical scope in the expression `x + y`. The most common
+use of `with` is in conjunction with the `import` function. E.g.,
+
+ with (import ./definitions.nix); ...
+
+makes all attributes defined in the file `definitions.nix` available as
+if they were defined locally in a `let`-expression.
+
+The bindings introduced by `with` do not shadow bindings introduced by
+other means, e.g.
+
+ let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...
+
+establishes the same scope as
+
+ let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
+
+Comments can be single-line, started with a `#` character, or
+inline/multi-line, enclosed within `/*
+... */`.
+
+1. Actually, Nix detects infinite recursion in this case and aborts
+ (“infinite recursion encountered”).
diff --git a/doc/manual/src/expressions/language-operators.md b/doc/manual/src/expressions/language-operators.md
new file mode 100644
index 000000000..4fa2eca37
--- /dev/null
+++ b/doc/manual/src/expressions/language-operators.md
@@ -0,0 +1,32 @@
+# Operators
+
+[table\_title](#table-operators) lists the operators in the Nix
+expression language, in order of precedence (from strongest to weakest
+binding).
+
+| Name | Syntax | Associativity | Description | Precedence |
+| ------------------------ | ----------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| Select | e `.` attrpath \[ `or` def \] | none | Select attribute denoted by the attribute path attrpath from set e. (An attribute path is a dot-separated list of attribute names.) If the attribute doesn’t exist, return def if provided, otherwise abort evaluation. | 1 |
+| Application | e1 e2 | left | Call function e1 with argument e2. | 2 |
+| Arithmetic Negation | `-` e | none | Arithmetic negation. | 3 |
+| Has Attribute | e `?` attrpath | none | Test whether set e contains the attribute denoted by attrpath; return `true` or `false`. | 4 |
+| List Concatenation | e1 `++` e2 | right | List concatenation. | 5 |
+| Multiplication | e1 `*` e2, | left | Arithmetic multiplication. | 6 |
+| Division | e1 `/` e2 | left | Arithmetic division. | 6 |
+| Addition | e1 `+` e2 | left | Arithmetic addition. | 7 |
+| Subtraction | e1 `-` e2 | left | Arithmetic subtraction. | 7 |
+| String Concatenation | string1 `+` string2 | left | String concatenation. | 7 |
+| Not | `!` e | none | Boolean negation. | 8 |
+| Update | e1 `//` e2 | right | Return a set consisting of the attributes in e1 and e2 (with the latter taking precedence over the former in case of equally named attributes). | 9 |
+| Less Than | e1 `<` e2, | none | Arithmetic comparison. | 10 |
+| Less Than or Equal To | e1 `<=` e2 | none | Arithmetic comparison. | 10 |
+| Greater Than | e1 `>` e2 | none | Arithmetic comparison. | 10 |
+| Greater Than or Equal To | e1 `>=` e2 | none | Arithmetic comparison. | 10 |
+| Equality | e1 `==` e2 | none | Equality. | 11 |
+| Inequality | e1 `!=` e2 | none | Inequality. | 11 |
+| Logical AND | e1 `&&` e2 | left | Logical AND. | 12 |
+| Logical OR | e1 `\|\|` e2 | left | Logical OR. | 13 |
+| Logical Implication | e1 `->` e2 | none | Logical implication (equivalent to `!e1 \|\|
+ e2`). | 14 |
+
+Operators
diff --git a/doc/manual/src/expressions/language-values.md b/doc/manual/src/expressions/language-values.md
new file mode 100644
index 000000000..98ad97c97
--- /dev/null
+++ b/doc/manual/src/expressions/language-values.md
@@ -0,0 +1,209 @@
+# Values
+
+Nix has the following basic data types:
+
+ - *Strings* can be written in three ways.
+
+ The most common way is to enclose the string between double quotes,
+ e.g., `"foo bar"`. Strings can span multiple lines. The special
+ characters `"` and `\` and the character sequence `${` must be
+ escaped by prefixing them with a backslash (`\`). Newlines, carriage
+ returns and tabs can be written as `\n`, `\r` and `\t`,
+ respectively.
+
+ You can include the result of an expression into a string by
+ enclosing it in `${...}`, a feature known as *antiquotation*. The
+ enclosed expression must evaluate to something that can be coerced
+ into a string (meaning that it must be a string, a path, or a
+ derivation). For instance, rather than writing
+
+ "--with-freetype2-library=" + freetype + "/lib"
+
+ (where `freetype` is a derivation), you can instead write the more
+ natural
+
+ "--with-freetype2-library=${freetype}/lib"
+
+ The latter is automatically translated to the former. A more
+ complicated example (from the Nix expression for
+ [Qt](http://www.trolltech.com/products/qt)):
+
+ configureFlags = "
+ -system-zlib -system-libpng -system-libjpeg
+ ${if openglSupport then "-dlopen-opengl
+ -L${mesa}/lib -I${mesa}/include
+ -L${libXmu}/lib -I${libXmu}/include" else ""}
+ ${if threadSupport then "-thread" else "-no-thread"}
+ ";
+
+ Note that Nix expressions and strings can be arbitrarily nested; in
+ this case the outer string contains various antiquotations that
+ themselves contain strings (e.g., `"-thread"`), some of which in
+ turn contain expressions (e.g., `${mesa}`).
+
+ The second way to write string literals is as an *indented string*,
+ which is enclosed between pairs of *double single-quotes*, like so:
+
+ ''
+ This is the first line.
+ This is the second line.
+ This is the third line.
+ ''
+
+ This kind of string literal intelligently strips indentation from
+ the start of each line. To be precise, it strips from each line a
+ number of spaces equal to the minimal indentation of the string as a
+ whole (disregarding the indentation of empty lines). For instance,
+ the first and second line are indented two space, while the third
+ line is indented four spaces. Thus, two spaces are stripped from
+ each line, so the resulting string is
+
+ "This is the first line.\nThis is the second line.\n This is the third line.\n"
+
+ Note that the whitespace and newline following the opening `''` is
+ ignored if there is no non-whitespace text on the initial line.
+
+ Antiquotation (`${expr}`) is supported in indented strings.
+
+ Since `${` and `''` have special meaning in indented strings, you
+ need a way to quote them. `$` can be escaped by prefixing it with
+ `''` (that is, two single quotes), i.e., `''$`. `''` can be escaped
+ by prefixing it with `'`, i.e., `'''`. `$` removes any special
+ meaning from the following `$`. Linefeed, carriage-return and tab
+ characters can be written as `''\n`, `''\r`, `''\t`, and `''\`
+ escapes any other character.
+
+ Indented strings are primarily useful in that they allow multi-line
+ string literals to follow the indentation of the enclosing Nix
+ expression, and that less escaping is typically necessary for
+ strings representing languages such as shell scripts and
+ configuration files because `''` is much less common than `"`.
+ Example:
+
+ stdenv.mkDerivation {
+ ...
+ postInstall =
+ ''
+ mkdir $out/bin $out/etc
+ cp foo $out/bin
+ echo "Hello World" > $out/etc/foo.conf
+ ${if enableBar then "cp bar $out/bin" else ""}
+ '';
+ ...
+ }
+
+ Finally, as a convenience, *URIs* as defined in appendix B of
+ [RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
+ is*, without quotes. For instance, the string
+ `"http://example.org/foo.tar.bz2"` can also be written as
+ `http://example.org/foo.tar.bz2`.
+
+ - Numbers, which can be *integers* (like `123`) or *floating point*
+ (like `123.43` or `.27e13`).
+
+ Numbers are type-compatible: pure integer operations will always
+ return integers, whereas any operation involving at least one
+ floating point number will have a floating point number as a result.
+
+ - *Paths*, e.g., `/bin/sh` or `./builder.sh`. A path must contain at
+ least one slash to be recognised as such; for instance, `builder.sh`
+ is not a path\[1\]. If the file name is relative, i.e., if it does
+ not begin with a slash, it is made absolute at parse time relative
+ to the directory of the Nix expression that contained it. For
+ instance, if a Nix expression in `/foo/bar/bla.nix` refers to
+ `../xyzzy/fnord.nix`, the absolute path is `/foo/xyzzy/fnord.nix`.
+
+ If the first component of a path is a `~`, it is interpreted as if
+ the rest of the path were relative to the user's home directory.
+ e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
+ whose home directory is `/home/edolstra`.
+
+ Paths can also be specified between angle brackets, e.g.
+ `<nixpkgs>`. This means that the directories listed in the
+ environment variable NIX\_PATH will be searched for the given file
+ or directory name.
+
+ - *Booleans* with values `true` and `false`.
+
+ - The null value, denoted as `null`.
+
+Lists are formed by enclosing a whitespace-separated list of values
+between square brackets. For example,
+
+ [ 123 ./foo.nix "abc" (f { x = y; }) ]
+
+defines a list of four elements, the last being the result of a call to
+the function `f`. Note that function calls have to be enclosed in
+parentheses. If they had been omitted, e.g.,
+
+ [ 123 ./foo.nix "abc" f { x = y; } ]
+
+the result would be a list of five elements, the fourth one being a
+function and the fifth being a set.
+
+Note that lists are only lazy in values, and they are strict in length.
+
+Sets are really the core of the language, since ultimately the Nix
+language is all about creating derivations, which are really just sets
+of attributes to be passed to build scripts.
+
+Sets are just a list of name/value pairs (called *attributes*) enclosed
+in curly brackets, where each value is an arbitrary expression
+terminated by a semicolon. For example:
+
+ { x = 123;
+ text = "Hello";
+ y = f { bla = 456; };
+ }
+
+This defines a set with attributes named `x`, `text`, `y`. The order of
+the attributes is irrelevant. An attribute name may only occur once.
+
+Attributes can be selected from a set using the `.` operator. For
+instance,
+
+ { a = "Foo"; b = "Bar"; }.a
+
+evaluates to `"Foo"`. It is possible to provide a default value in an
+attribute selection using the `or` keyword. For example,
+
+ { a = "Foo"; b = "Bar"; }.c or "Xyzzy"
+
+will evaluate to `"Xyzzy"` because there is no `c` attribute in the set.
+
+You can use arbitrary double-quoted strings as attribute names:
+
+ { "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
+
+This will evaluate to `123` (Assuming `bar` is antiquotable). In the
+case where an attribute name is just a single antiquotation, the quotes
+can be dropped:
+
+ { foo = 123; }.${bar} or 456
+
+This will evaluate to `123` if `bar` evaluates to `"foo"` when coerced
+to a string and `456` otherwise (again assuming `bar` is antiquotable).
+
+In the special case where an attribute name inside of a set declaration
+evaluates to `null` (which is normally an error, as `null` is not
+antiquotable), that attribute is simply not added to the set:
+
+ { ${if foo then "bar" else null} = true; }
+
+This will evaluate to `{}` if `foo` evaluates to `false`.
+
+A set that has a `__functor` attribute whose value is callable (i.e. is
+itself a function or a set with a `__functor` attribute whose value is
+callable) can be applied as if it were a function, with the set itself
+passed in first , e.g.,
+
+ let add = { __functor = self: x: x + self.x; };
+ inc = add // { x = 1; };
+ in inc 1
+
+evaluates to `2`. This can be used to attach metadata to a function
+without the caller needing to treat it specially, or to implement a form
+of object-oriented programming, for example.
+
+1. It's parsed as an expression that selects the attribute `sh` from
+ the variable `builder`.
diff --git a/doc/manual/src/expressions/simple-building-testing.md b/doc/manual/src/expressions/simple-building-testing.md
new file mode 100644
index 000000000..bc064c733
--- /dev/null
+++ b/doc/manual/src/expressions/simple-building-testing.md
@@ -0,0 +1,57 @@
+# Building and Testing
+
+You can now try to build Hello. Of course, you could do `nix-env -i
+hello`, but you may not want to install a possibly broken package just
+yet. The best way to test the package is by using the command
+`nix-build`, which builds a Nix expression and creates a symlink named
+`result` in the current directory:
+
+ $ nix-build -A hello
+ building path `/nix/store/632d2b22514d...-hello-2.1.1'
+ hello-2.1.1/
+ hello-2.1.1/intl/
+ hello-2.1.1/intl/ChangeLog
+ ...
+
+ $ ls -l result
+ lrwxrwxrwx ... 2006-09-29 10:43 result -> /nix/store/632d2b22514d...-hello-2.1.1
+
+ $ ./result/bin/hello
+ Hello, world!
+
+The [`-A`](#opt-attr) option selects the `hello` attribute. This is
+faster than using the symbolic package name specified by the `name`
+attribute (which also happens to be `hello`) and is unambiguous (there
+can be multiple packages with the symbolic name `hello`, but there can
+be only one attribute in a set named `hello`).
+
+`nix-build` registers the `./result` symlink as a garbage collection
+root, so unless and until you delete the `./result` symlink, the output
+of the build will be safely kept on your system. You can use
+`nix-build`’s `-o` switch to give the symlink another name.
+
+Nix has transactional semantics. Once a build finishes successfully, Nix
+makes a note of this in its database: it registers that the path denoted
+by out is now “valid”. If you try to build the derivation again, Nix
+will see that the path is already valid and finish immediately. If a
+build fails, either because it returns a non-zero exit code, because Nix
+or the builder are killed, or because the machine crashes, then the
+output paths will not be registered as valid. If you try to build the
+derivation again, Nix will remove the output paths if they exist (e.g.,
+because the builder died half-way through `make
+install`) and try again. Note that there is no “negative caching”: Nix
+doesn't remember that a build failed, and so a failed build can always
+be repeated. This is because Nix cannot distinguish between permanent
+failures (e.g., a compiler error due to a syntax error in the source)
+and transient failures (e.g., a disk full condition).
+
+Nix also performs locking. If you run multiple Nix builds
+simultaneously, and they try to build the same derivation, the first Nix
+instance that gets there will perform the build, while the others block
+(or perform other derivations if available) until the build finishes:
+
+ $ nix-build -A hello
+ waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'
+
+So it is always safe to run multiple instances of Nix in parallel (which
+isn’t the case with, say, `make`).
diff --git a/doc/manual/src/expressions/simple-expression.md b/doc/manual/src/expressions/simple-expression.md
new file mode 100644
index 000000000..9023f97a4
--- /dev/null
+++ b/doc/manual/src/expressions/simple-expression.md
@@ -0,0 +1,27 @@
+# A Simple Nix Expression
+
+This section shows how to add and test the [GNU Hello
+package](http://www.gnu.org/software/hello/hello.html) to the Nix
+Packages collection. Hello is a program that prints out the text “Hello,
+world\!”.
+
+To add a package to the Nix Packages collection, you generally need to
+do three things:
+
+1. Write a Nix expression for the package. This is a file that
+ describes all the inputs involved in building the package, such as
+ dependencies, sources, and so on.
+
+2. Write a *builder*. This is a shell script\[1\] that actually builds
+ the package from the inputs.
+
+3. Add the package to the file `pkgs/top-level/all-packages.nix`. The
+ Nix expression written in the first step is a *function*; it
+ requires other packages in order to build it. In this step you put
+ it all together, i.e., you call the function with the right
+ arguments to build the actual package.
+
+<!-- end list -->
+
+1. In fact, it can be written in any language, but typically it's a
+ `bash` shell script.
diff --git a/doc/manual/src/expressions/writing-nix-expressions.md b/doc/manual/src/expressions/writing-nix-expressions.md
new file mode 100644
index 000000000..5664108e7
--- /dev/null
+++ b/doc/manual/src/expressions/writing-nix-expressions.md
@@ -0,0 +1,12 @@
+This chapter shows you how to write Nix expressions, which instruct Nix
+how to build packages. It starts with a simple example (a Nix expression
+for GNU Hello), and then moves on to a more in-depth look at the Nix
+expression language.
+
+> **Note**
+>
+> This chapter is mostly about the Nix expression language. For more
+> extensive information on adding packages to the Nix Packages
+> collection (such as functions in the standard environment and coding
+> conventions), please consult [its
+> manual](http://nixos.org/nixpkgs/manual/).