aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/src/language
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/src/language')
-rw-r--r--doc/manual/src/language/advanced-attributes.md257
-rw-r--r--doc/manual/src/language/builtin-constants.md20
-rw-r--r--doc/manual/src/language/builtins-prefix.md16
-rw-r--r--doc/manual/src/language/builtins-suffix.md1
-rw-r--r--doc/manual/src/language/constructs.md354
-rw-r--r--doc/manual/src/language/derivations.md161
-rw-r--r--doc/manual/src/language/index.md581
-rw-r--r--doc/manual/src/language/operators.md167
-rw-r--r--doc/manual/src/language/string-interpolation.md82
-rw-r--r--doc/manual/src/language/values.md251
10 files changed, 1890 insertions, 0 deletions
diff --git a/doc/manual/src/language/advanced-attributes.md b/doc/manual/src/language/advanced-attributes.md
new file mode 100644
index 000000000..2e7e80ed0
--- /dev/null
+++ b/doc/manual/src/language/advanced-attributes.md
@@ -0,0 +1,257 @@
+# Advanced Attributes
+
+Derivations can declare some infrequently used optional attributes.
+
+ - [`allowedReferences`]{#adv-attr-allowedReferences}\
+ The optional attribute `allowedReferences` specifies a list of legal
+ references (dependencies) of the output of the builder. For example,
+
+ ```nix
+ 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`]{#adv-attr-allowedRequisites}\
+ This attribute is similar to `allowedReferences`, but it specifies
+ the legal requisites of the whole closure, so all the dependencies
+ recursively. For example,
+
+ ```nix
+ 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`]{#adv-attr-disallowedReferences}\
+ The optional attribute `disallowedReferences` specifies a list of
+ illegal references (dependencies) of the output of the builder. For
+ example,
+
+ ```nix
+ disallowedReferences = [ foo ];
+ ```
+
+ enforces that the output of a derivation cannot have a direct
+ runtime dependencies on the derivation `foo`.
+
+ - [`disallowedRequisites`]{#adv-attr-disallowedRequisites}\
+ This attribute is similar to `disallowedReferences`, but it
+ specifies illegal requisites for the whole closure, so all the
+ dependencies recursively. For example,
+
+ ```nix
+ 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`]{#adv-attr-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:
+
+ ```nix
+ 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`]{#adv-attr-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
+
+ ```nix
+ 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* (see
+ below), 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`]{#adv-attr-outputHash}; [`outputHashAlgo`]{#adv-attr-outputHashAlgo}; [`outputHashMode`]{#adv-attr-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,
+
+ ```nix
+ 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.,
+
+ ```nix
+ 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`:
+
+ ```nix
+ { 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`](../command-ref/nix-store.md#operation---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](../command-ref/nix-hash.md) for information
+ about converting to and from base-32 notation.)
+
+ - [`__contentAddressed`]{#adv-attr-__contentAddressed}
+ If this **experimental** attribute is set to true, then the derivation
+ outputs will be stored in a content-addressed location rather than the
+ traditional input-addressed one.
+ This only has an effect if the `ca-derivation` experimental feature is enabled.
+
+ Setting this attribute also requires setting `outputHashMode` and `outputHashAlgo` like for *fixed-output derivations* (see above).
+
+ - [`passAsFile`]{#adv-attr-passAsFile}\
+ A list of names of attributes that should be passed via files rather
+ than environment variables. For example, if you have
+
+ ```nix
+ 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`]{#adv-attr-preferLocalBuild}\
+ If this attribute is set to `true` and [distributed building is
+ enabled](../advanced-topics/distributed-builds.md), then, if
+ possible, the derivation 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`]{#adv-attr-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/language/builtin-constants.md b/doc/manual/src/language/builtin-constants.md
new file mode 100644
index 000000000..78d066a82
--- /dev/null
+++ b/doc/manual/src/language/builtin-constants.md
@@ -0,0 +1,20 @@
+# Built-in Constants
+
+Here are the constants built into the Nix expression evaluator:
+
+ - `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.,
+
+ ```nix
+ 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.currentSystem`]{#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"`.
diff --git a/doc/manual/src/language/builtins-prefix.md b/doc/manual/src/language/builtins-prefix.md
new file mode 100644
index 000000000..c631a8453
--- /dev/null
+++ b/doc/manual/src/language/builtins-prefix.md
@@ -0,0 +1,16 @@
+# Built-in Functions
+
+This section lists the functions 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`.
+
+<dl>
+ <dt><code>derivation <var>attrs</var></code>;
+ <code>builtins.derivation <var>attrs</var></code></dt>
+ <dd><p><var>derivation</var> is described in
+ <a href="derivations.md">its own section</a>.</p></dd>
diff --git a/doc/manual/src/language/builtins-suffix.md b/doc/manual/src/language/builtins-suffix.md
new file mode 100644
index 000000000..a74db2857
--- /dev/null
+++ b/doc/manual/src/language/builtins-suffix.md
@@ -0,0 +1 @@
+</dl>
diff --git a/doc/manual/src/language/constructs.md b/doc/manual/src/language/constructs.md
new file mode 100644
index 000000000..1c01f2cc7
--- /dev/null
+++ b/doc/manual/src/language/constructs.md
@@ -0,0 +1,354 @@
+# Language Constructs
+
+## Recursive sets
+
+Recursive sets are just normal sets, but the attributes can refer to
+each other. For example,
+
+```nix
+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, the expression
+
+```nix
+rec {
+ x = y;
+ y = x;
+}.x
+```
+
+will crash with an `infinite recursion encountered` error message.
+
+## Let-expressions
+
+A let-expression allows you to define local variables for an expression.
+For instance,
+
+```nix
+let
+ x = "foo";
+ y = "bar";
+in x + y
+```
+
+evaluates to `"foobar"`.
+
+## Inheriting attributes
+
+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,
+
+```nix
+let x = 123; in
+{ inherit x;
+ y = 456;
+}
+```
+
+is equivalent to
+
+```nix
+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`,
+
+```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
+
+```nix
+...
+inherit x y z;
+inherit (src-set) a b c;
+...
+```
+
+is equivalent to
+
+```nix
+...
+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
+
+Functions have the following form:
+
+```nix
+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:
+
+ ```nix
+ 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.,
+
+ ```nix
+ 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
+
+ ```nix
+ { 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 (`...`):
+
+ ```nix
+ { 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,
+
+ ```nix
+ { 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:
+
+ ```nix
+ args@{ x, y, z, ... }: z + y + x + args.a
+ ```
+
+ but can also be written as:
+
+ ```nix
+ { 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
+ >
+ > ```nix
+ > 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.,
+
+```nix
+let concat = { x, y }: x + y;
+in concat { x = "foo"; y = "bar"; }
+```
+
+## Conditionals
+
+Conditionals look like this:
+
+```nix
+if e1 then e2 else e3
+```
+
+where *e1* is an expression that should evaluate to a Boolean value
+(`true` or `false`).
+
+## Assertions
+
+Assertions are generally used to check that certain requirements on or
+between features and dependencies hold. They look like this:
+
+```nix
+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.
+
+Here is a Nix expression for the Subversion package that shows how
+assertions can be used:.
+
+```nix
+{ 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; ④
+ ...
+}
+```
+
+The points of interest are:
+
+1. 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.
+
+ Note that `->` is the [logical
+ implication](https://en.wikipedia.org/wiki/Truth_table#Logical_implication)
+ Boolean operation.
+
+2. 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.
+
+3. 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.)
+
+4. 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.
+
+## With-expressions
+
+A *with-expression*,
+
+```nix
+with e1; e2
+```
+
+introduces the set *e1* into the lexical scope of the expression *e2*.
+For instance,
+
+```nix
+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.,
+
+```nix
+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.
+
+```nix
+let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...
+```
+
+establishes the same scope as
+
+```nix
+let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
+```
+
+## Comments
+
+Comments can be single-line, started with a `#` character, or
+inline/multi-line, enclosed within `/* ... */`.
diff --git a/doc/manual/src/language/derivations.md b/doc/manual/src/language/derivations.md
new file mode 100644
index 000000000..043a38191
--- /dev/null
+++ b/doc/manual/src/language/derivations.md
@@ -0,0 +1,161 @@
+# Derivations
+
+The most important built-in function is `derivation`, which is used to
+describe a single derivation (a build task). It takes as input a set,
+the attributes of which specify the inputs of the build.
+
+ - There must be an attribute named [`system`]{#attr-system} whose value must be a
+ string specifying a Nix system type, such as `"i686-linux"` or
+ `"x86_64-darwin"`. (To figure out your system type, run `nix -vv
+ --version`.) The build can only be performed on a machine and
+ operating system matching the system type. (Nix can automatically
+ [forward builds for other
+ platforms](../advanced-topics/distributed-builds.md) by forwarding
+ them to other machines.)
+
+ - 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:
+
+ ```nix
+ 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
+
+ ```bash
+ ./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.
+
+ ```nix
+ buildInputs = [ pkg.lib pkg.headers ];
+ ```
+
+ The first element of `outputs` determines the *default output*.
+ Thus, you could also write
+
+ ```nix
+ 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.
diff --git a/doc/manual/src/language/index.md b/doc/manual/src/language/index.md
new file mode 100644
index 000000000..db34fde75
--- /dev/null
+++ b/doc/manual/src/language/index.md
@@ -0,0 +1,581 @@
+# Nix Language
+
+The Nix language is
+
+- *domain-specific*
+
+ It only exists for the Nix package manager:
+ to describe packages and configurations as well as their variants and compositions.
+ It is not intended for general purpose use.
+
+- *declarative*
+
+ There is no notion of executing sequential steps.
+ Dependencies between operations are established only through data.
+
+- *pure*
+
+ Values cannot change during computation.
+ Functions always produce the same output if their input does not change.
+
+- *functional*
+
+ Functions are like any other value.
+ Functions can be assigned to names, taken as arguments, or returned by functions.
+
+- *lazy*
+
+ Expressions are only evaluated when their value is needed.
+
+- *dynamically typed*
+
+ Type errors are only detected when expressions are evaluated.
+
+# Overview
+
+This is an incomplete overview of language features, by example.
+
+<table>
+ <tr>
+ <th>
+ Example
+ </th>
+ <th>
+ Description
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ *Basic values*
+
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `"hello world"`
+
+ </td>
+ <td>
+
+ A string
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ ```
+ ''
+ multi
+ line
+ string
+ ''
+ ```
+
+ </td>
+ <td>
+
+ A multi-line string. Strips common prefixed whitespace. Evaluates to `"multi\n line\n string"`.
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `"hello ${ { a = "world" }.a }"`
+
+ `"1 2 ${toString 3}"`
+
+ `"${pkgs.bash}/bin/sh"`
+
+ </td>
+ <td>
+
+ String interpolation (expands to `"hello world"`, `"1 2 3"`, `"/nix/store/<hash>-bash-<version>/bin/sh"`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `true`, `false`
+
+ </td>
+ <td>
+
+ Booleans
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `null`
+
+ </td>
+ <td>
+
+ Null value
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `123`
+
+ </td>
+ <td>
+
+ An integer
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `3.141`
+
+ </td>
+ <td>
+
+ A floating point number
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `/etc`
+
+ </td>
+ <td>
+
+ An absolute path
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `./foo.png`
+
+ </td>
+ <td>
+
+ A path relative to the file containing this Nix expression
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `~/.config`
+
+ </td>
+ <td>
+
+ A home path. Evaluates to the `"<user's home directory>/.config"`.
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ <nixpkgs>
+
+ </td>
+ <td>
+
+ Search path. Value determined by [`$NIX_PATH` environment variable](../command-ref/env-common.md#env-NIX_PATH).
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ *Compound values*
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x = 1; y = 2; }`
+
+ </td>
+ <td>
+
+ A set with attributes named `x` and `y`
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ foo.bar = 1; }`
+
+ </td>
+ <td>
+
+ A nested set, equivalent to `{ foo = { bar = 1; }; }`
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `rec { x = "foo"; y = x + "bar"; }`
+
+ </td>
+ <td>
+
+ A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }`
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `[ "foo" "bar" "baz" ]`
+
+ `[ 1 2 3 ]`
+
+ `[ (f 1) { a = 1; b = 2; } [ "c" ] ]`
+
+ </td>
+ <td>
+
+ Lists with three elements.
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ *Operators*
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `"foo" + "bar"`
+
+ </td>
+ <td>
+
+ String concatenation
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `1 + 2`
+
+ </td>
+ <td>
+
+ Integer addition
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `"foo" == "f" + "oo"`
+
+ </td>
+ <td>
+
+ Equality test (evaluates to `true`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `"foo" != "bar"`
+
+ </td>
+ <td>
+
+ Inequality test (evaluates to `true`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `!true`
+
+ </td>
+ <td>
+
+ Boolean negation
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x = 1; y = 2; }.x`
+
+ </td>
+ <td>
+
+ Attribute selection (evaluates to `1`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x = 1; y = 2; }.z or 3`
+
+ </td>
+ <td>
+
+ Attribute selection with default (evaluates to `3`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x = 1; y = 2; } // { z = 3; }`
+
+ </td>
+ <td>
+
+ Merge two sets (attributes in the right-hand set taking precedence)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ *Control structures*
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `if 1 + 1 == 2 then "yes!" else "no!"`
+
+ </td>
+ <td>
+
+ Conditional expression
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `assert 1 + 1 == 2; "yes!"`
+
+ </td>
+ <td>
+
+ Assertion check (evaluates to `"yes!"`).
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `let x = "foo"; y = "bar"; in x + y`
+
+ </td>
+ <td>
+
+ Variable definition
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `with builtins; head [ 1 2 3 ]`
+
+ </td>
+ <td>
+
+ Add all attributes from the given set to the scope (evaluates to `1`)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ *Functions (lambdas)*
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `x: x + 1`
+
+ </td>
+ <td>
+
+ A function that expects an integer and returns it increased by 1
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `x: y: x + y`
+
+ </td>
+ <td>
+
+ Curried function, equivalent to `x: (y: x + y)`. Can be used like a function that takes two arguments and returns their sum.
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `(x: x + 1) 100`
+
+ </td>
+ <td>
+
+ A function call (evaluates to 101)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `let inc = x: x + 1; in inc (inc (inc 100))`
+
+ </td>
+ <td>
+
+ A function bound to a variable and subsequently called by name (evaluates to 103)
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x, y }: x + y`
+
+ </td>
+ <td>
+
+ A function that expects a set with required attributes `x` and `y` and concatenates them
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x, y ? "bar" }: x + y`
+
+ </td>
+ <td>
+
+ A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y`
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x, y, ... }: x + y`
+
+ </td>
+ <td>
+
+ A function that expects a set with required attributes `x` and `y` and ignores any other attributes
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `{ x, y } @ args: x + y`
+
+ `args @ { x, y }: x + y`
+
+ </td>
+ <td>
+
+ A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args`
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ *Built-in functions*
+
+ </td>
+ <td>
+
+
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `import ./foo.nix`
+
+ </td>
+ <td>
+
+ Load and return Nix expression in given file
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+
+ `map (x: x + x) [ 1 2 3 ]`
+
+ </td>
+ <td>
+
+ Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`)
+
+ </td>
+ </tr>
+</table>
diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md
new file mode 100644
index 000000000..797f13bd3
--- /dev/null
+++ b/doc/manual/src/language/operators.md
@@ -0,0 +1,167 @@
+# Operators
+
+| Name | Syntax | Associativity | Precedence |
+|----------------------------------------|--------------------------------------------|---------------|------------|
+| [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 |
+| Function application | *func* *expr* | left | 2 |
+| [Arithmetic negation][arithmetic] | `-` *number* | none | 3 |
+| [Has attribute] | *attrset* `?` *attrpath* | none | 4 |
+| List concatenation | *list* `++` *list* | right | 5 |
+| [Multiplication][arithmetic] | *number* `*` *number* | left | 6 |
+| [Division][arithmetic] | *number* `/` *number* | left | 6 |
+| [Subtraction][arithmetic] | *number* `-` *number* | left | 7 |
+| [Addition][arithmetic] | *number* `+` *number* | left | 7 |
+| [String concatenation] | *string* `+` *string* | left | 7 |
+| [Path concatenation] | *path* `+` *path* | left | 7 |
+| [Path and string concatenation] | *path* `+` *string* | left | 7 |
+| [String and path concatenation] | *string* `+` *path* | left | 7 |
+| Logical negation (`NOT`) | `!` *bool* | none | 8 |
+| [Update] | *attrset* `//` *attrset* | right | 9 |
+| [Less than][Comparison] | *expr* `<` *expr* | none | 10 |
+| [Less than or equal to][Comparison] | *expr* `<=` *expr* | none | 10 |
+| [Greater than][Comparison] | *expr* `>` *expr* | none | 10 |
+| [Greater than or equal to][Comparison] | *expr* `>=` *expr* | none | 10 |
+| [Equality] | *expr* `==` *expr* | none | 11 |
+| Inequality | *expr* `!=` *expr* | none | 11 |
+| Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 |
+| Logical disjunction (`OR`) | *bool* `||` *bool* | left | 13 |
+| [Logical implication] | *bool* `->` *bool* | none | 14 |
+
+[string]: ./values.md#type-string
+[path]: ./values.md#type-path
+[number]: ./values.md#type-number
+[list]: ./values.md#list
+[attribute set]: ./values.md#attribute-set
+
+## Attribute selection
+
+Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
+If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation.
+
+<!-- FIXME: the following should to into its own language syntax section, but that needs more work to fit in well -->
+
+An attribute path is a dot-separated list of attribute names.
+An attribute name can be an identifier or a string.
+
+> *attrpath* = *name* [ `.` *name* ]...
+> *name* = *identifier* | *string*
+> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
+
+[Attribute selection]: #attribute-selection
+
+## Has attribute
+
+> *attrset* `?` *attrpath*
+
+Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*.
+The result is a [Boolean] value.
+
+[Boolean]: ./values.md#type-boolean
+
+[Has attribute]: #has-attribute
+
+## Arithmetic
+
+Numbers are type-compatible:
+Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number.
+
+See also [Comparison] and [Equality].
+
+The `+` operator is overloaded to also work on strings and paths.
+
+[arithmetic]: #arithmetic
+
+## String concatenation
+
+> *string* `+` *string*
+
+Concatenate two [string]s and merge their string contexts.
+
+[String concatenation]: #string-concatenation
+
+## Path concatenation
+
+> *path* `+` *path*
+
+Concatenate two [path]s.
+The result is a path.
+
+[Path concatenation]: #path-concatenation
+
+## Path and string concatenation
+
+> *path* + *string*
+
+Concatenate *[path]* with *[string]*.
+The result is a path.
+
+> **Note**
+>
+> The string must not have a string context that refers to a [store path].
+
+[Path and string concatenation]: #path-and-string-concatenation
+
+## String and path concatenation
+
+> *string* + *path*
+
+Concatenate *[string]* with *[path]*.
+The result is a string.
+
+> **Important**
+>
+> The file or directory at *path* must exist and is copied to the [store].
+> The path appears in the result as the corresponding [store path].
+
+[store path]: ../glossary.md#gloss-store-path
+[store]: ../glossary.md#gloss-store
+
+[Path and string concatenation]: #path-and-string-concatenation
+
+## Update
+
+> *attrset1* + *attrset2*
+
+Update [attribute set] *attrset1* with names and values from *attrset2*.
+
+The returned attribute set will have of all the attributes in *e1* and *e2*.
+If an attribute name is present in both, the attribute value from the former is taken.
+
+[Update]: #update
+
+## Comparison
+
+Comparison is
+
+- [arithmetic] for [number]s
+- lexicographic for [string]s and [path]s
+- item-wise lexicographic for [list]s:
+ elements at the same index in both lists are compared according to their type and skipped if they are equal.
+
+All comparison operators are implemented in terms of `<`, and the following equivalencies hold:
+
+| comparison | implementation |
+|--------------|-----------------------|
+| *a* `<=` *b* | `! (` *b* `<` *a* `)` |
+| *a* `>` *b* | *b* `<` *a* |
+| *a* `>=` *b* | `! (` *a* `<` *b* `)` |
+
+[Comparison]: #comparison-operators
+
+## Equality
+
+- [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated.
+- Comparison of [function]s always returns `false`.
+- Numbers are type-compatible, see [arithmetic] operators.
+- Floating point numbers only differ up to a limited precision.
+
+[function]: ./constructs.md#functions
+
+[Equality]: #equality
+
+## Logical implication
+
+Equivalent to `!`*b1* `||` *b2*.
+
+[Logical implication]: #logical-implication
+
diff --git a/doc/manual/src/language/string-interpolation.md b/doc/manual/src/language/string-interpolation.md
new file mode 100644
index 000000000..ddc6b8230
--- /dev/null
+++ b/doc/manual/src/language/string-interpolation.md
@@ -0,0 +1,82 @@
+# String interpolation
+
+String interpolation is a language feature where a [string], [path], or [attribute name] can contain expressions enclosed in `${ }` (dollar-sign with curly brackets).
+
+Such a string is an *interpolated string*, and an expression inside is an *interpolated expression*.
+
+Interpolated expressions must evaluate to one of the following:
+
+- a [string]
+- a [path]
+- a [derivation]
+
+[string]: ./values.md#type-string
+[path]: ./values.md#type-path
+[attribute name]: ./values.md#attribute-set
+[derivation]: ../glossary.md#gloss-derivation
+
+## Examples
+
+### String
+
+Rather than writing
+
+```nix
+"--with-freetype2-library=" + freetype + "/lib"
+```
+
+(where `freetype` is a [derivation]), you can instead write
+
+```nix
+"--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)):
+
+```nix
+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 interpolated expressions that themselves contain strings (e.g., `"-thread"`), some of which in turn contain interpolated expressions (e.g., `${mesa}`).
+
+### Path
+
+Rather than writing
+
+```nix
+./. + "/" + foo + "-" + bar + ".nix"
+```
+
+or
+
+```nix
+./. + "/${foo}-${bar}.nix"
+```
+
+you can instead write
+
+```nix
+./${foo}-${bar}.nix
+```
+
+### Attribute name
+
+Attribute names can be created dynamically with string interpolation:
+
+```nix
+let name = "foo"; in
+{
+ ${name} = "bar";
+}
+```
+
+ { foo = "bar"; }
diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md
new file mode 100644
index 000000000..3973518ca
--- /dev/null
+++ b/doc/manual/src/language/values.md
@@ -0,0 +1,251 @@
+# Data Types
+
+## Primitives
+
+- <a id="type-string" href="#type-string">String</a>
+
+ *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 results of other expressions into a string by enclosing them in `${ }`, a feature known as [string interpolation].
+
+ [string interpolation]: ./string-interpolation.md
+
+ The second way to write string literals is as an *indented string*,
+ which is enclosed between pairs of *double single-quotes*, like so:
+
+ ```nix
+ ''
+ 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 spaces, while the third
+ line is indented four spaces. Thus, two spaces are stripped from
+ each line, so the resulting string is
+
+ ```nix
+ "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.
+
+ Indented strings support [string interpolation].
+
+ 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:
+
+ ```nix
+ 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`.
+
+- <a id="type-number" href="#type-number">Number</a>
+
+ Numbers, which can be *integers* (like `123`) or *floating point*
+ (like `123.43` or `.27e13`).
+
+ See [arithmetic] and [comparison] operators for semantics.
+
+ [arithmetic]: ./operators.md#arithmetic
+ [comparison]: ./operators.md#comparison
+
+- <a id="type-path" href="#type-path">Path</a>
+
+ *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: it's parsed as an expression that selects the
+ attribute `sh` from the variable `builder`. 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.
+
+ When an [interpolated string][string interpolation] evaluates to a path, the path is first copied into the Nix store and the resulting string is the [store path] of the newly created [store object].
+
+ [store path]: ../glossary.md#gloss-store-path
+ [store object]: ../glossary.md#gloss-store-object
+
+ For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` in the current directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.
+
+ Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
+ For example, assume you used a file path in an interpolated string during a `nix repl` session.
+ Later in the same session, after having changed the file contents, evaluating the interpolated string with the file path again might not return a new store path, since Nix might not re-read the file contents.
+
+ Paths themselves, except those in angle brackets (`< >`), support [string interpolation].
+
+ At least one slash (`/`) must appear *before* any interpolated expression for the result to be recognized as a path.
+
+ `a.${foo}/b.${bar}` is a syntactically valid division operation.
+ `./a.${foo}/b.${bar}` is a path.
+
+- <a id="type-boolean" href="#type-boolean">Boolean</a>
+
+ *Booleans* with values `true` and `false`.
+
+- <a id="type-null" href="#type-null">Null</a>
+
+ The null value, denoted as `null`.
+
+## List
+
+Lists are formed by enclosing a whitespace-separated list of values
+between square brackets. For example,
+
+```nix
+[ 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.,
+
+```nix
+[ 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.
+
+## Attribute Set
+
+An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
+
+Names and values are separated by an equal sign (`=`).
+Each value is an arbitrary expression terminated by a semicolon (`;`).
+
+Attributes can appear in any order.
+An attribute name may only occur once.
+
+Example:
+
+```nix
+{
+ x = 123;
+ text = "Hello";
+ y = f { bla = 456; };
+}
+```
+
+This defines a set with attributes named `x`, `text`, `y`.
+
+Attributes can be selected from a set using the `.` operator. For
+instance,
+
+```nix
+{ 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,
+
+```nix
+{ 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:
+
+```nix
+{ "$!@#?" = 123; }."$!@#?"
+```
+
+```nix
+let bar = "bar";
+{ "foo ${bar}" = 123; }."foo ${bar}"
+```
+
+Both will evaluate to `123`.
+
+Attribute names support [string interpolation]:
+
+```nix
+let bar = "foo"; in
+{ foo = 123; }.${bar}
+```
+
+```nix
+let bar = "foo"; in
+{ ${bar} = 123; }.foo
+```
+
+Both will evaluate to `123`.
+
+In the special case where an attribute name inside of a set declaration
+evaluates to `null` (which is normally an error, as `null` cannot be coerced to
+a string), that attribute is simply not added to the set:
+
+```nix
+{ ${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.,
+
+```nix
+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.