+
+
+ Example
+ |
+
+ Description
+ |
+
+
+
+
+
+ *Basic values*
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `"hello world"`
+
+ |
+
+
+ A string
+
+ |
+
+
+
+
+ ```
+ ''
+ multi
+ line
+ string
+ ''
+ ```
+
+ |
+
+
+ A multi-line string. Strips common prefixed whitespace. Evaluates to `"multi\n line\n string"`.
+
+ |
+
+
+
+
+ `"hello ${ { a = "world" }.a }"`
+
+ `"1 2 ${toString 3}"`
+
+ `"${pkgs.bash}/bin/sh"`
+
+ |
+
+
+ String interpolation (expands to `"hello world"`, `"1 2 3"`, `"/nix/store/-bash-/bin/sh"`)
+
+ |
+
+
+
+
+ `true`, `false`
+
+ |
+
+
+ Booleans
+
+ |
+
+
+
+
+ `null`
+
+ |
+
+
+ Null value
+
+ |
+
+
+
+
+ `123`
+
+ |
+
+
+ An integer
+
+ |
+
+
+
+
+ `3.141`
+
+ |
+
+
+ A floating point number
+
+ |
+
+
+
+
+ `/etc`
+
+ |
+
+
+ An absolute path
+
+ |
+
+
+
+
+ `./foo.png`
+
+ |
+
+
+ A path relative to the file containing this Nix expression
+
+ |
+
+
+
+
+ `~/.config`
+
+ |
+
+
+ A home path. Evaluates to the `"/.config"`.
+
+ |
+
+
+
+
+
+
+ |
+
+
+ Search path. Value determined by [`$NIX_PATH` environment variable](../command-ref/env-common.md#env-NIX_PATH).
+
+ |
+
+
+
+
+ *Compound values*
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `{ x = 1; y = 2; }`
+
+ |
+
+
+ A set with attributes named `x` and `y`
+
+ |
+
+
+
+
+ `{ foo.bar = 1; }`
+
+ |
+
+
+ A nested set, equivalent to `{ foo = { bar = 1; }; }`
+
+ |
+
+
+
+
+ `rec { x = "foo"; y = x + "bar"; }`
+
+ |
+
+
+ A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }`
+
+ |
+
+
+
+
+ `[ "foo" "bar" "baz" ]`
+
+ `[ 1 2 3 ]`
+
+ `[ (f 1) { a = 1; b = 2; } [ "c" ] ]`
+
+ |
+
+
+ Lists with three elements.
+
+ |
+
+
+
+
+ *Operators*
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `"foo" + "bar"`
+
+ |
+
+
+ String concatenation
+
+ |
+
+
+
+
+ `1 + 2`
+
+ |
+
+
+ Integer addition
+
+ |
+
+
+
+
+ `"foo" == "f" + "oo"`
+
+ |
+
+
+ Equality test (evaluates to `true`)
+
+ |
+
+
+
+
+ `"foo" != "bar"`
+
+ |
+
+
+ Inequality test (evaluates to `true`)
+
+ |
+
+
+
+
+ `!true`
+
+ |
+
+
+ Boolean negation
+
+ |
+
+
+
+
+ `{ x = 1; y = 2; }.x`
+
+ |
+
+
+ Attribute selection (evaluates to `1`)
+
+ |
+
+
+
+
+ `{ x = 1; y = 2; }.z or 3`
+
+ |
+
+
+ Attribute selection with default (evaluates to `3`)
+
+ |
+
+
+
+
+ `{ x = 1; y = 2; } // { z = 3; }`
+
+ |
+
+
+ Merge two sets (attributes in the right-hand set taking precedence)
+
+ |
+
+
+
+
+ *Control structures*
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `if 1 + 1 == 2 then "yes!" else "no!"`
+
+ |
+
+
+ Conditional expression
+
+ |
+
+
+
+
+ `assert 1 + 1 == 2; "yes!"`
+
+ |
+
+
+ Assertion check (evaluates to `"yes!"`).
+
+ |
+
+
+
+
+ `let x = "foo"; y = "bar"; in x + y`
+
+ |
+
+
+ Variable definition
+
+ |
+
+
+
+
+ `with builtins; head [ 1 2 3 ]`
+
+ |
+
+
+ Add all attributes from the given set to the scope (evaluates to `1`)
+
+ |
+
+
+
+
+ *Functions (lambdas)*
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `x: x + 1`
+
+ |
+
+
+ A function that expects an integer and returns it increased by 1
+
+ |
+
+
+
+
+ `x: y: x + y`
+
+ |
+
+
+ Curried function, equivalent to `x: (y: x + y)`. Can be used like a function that takes two arguments and returns their sum.
+
+ |
+
+
+
+
+ `(x: x + 1) 100`
+
+ |
+
+
+ A function call (evaluates to 101)
+
+ |
+
+
+
+
+ `let inc = x: x + 1; in inc (inc (inc 100))`
+
+ |
+
+
+ A function bound to a variable and subsequently called by name (evaluates to 103)
+
+ |
+
+
+
+
+ `{ x, y }: x + y`
+
+ |
+
+
+ A function that expects a set with required attributes `x` and `y` and concatenates them
+
+ |
+
+
+
+
+ `{ x, y ? "bar" }: x + y`
+
+ |
+
+
+ A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y`
+
+ |
+
+
+
+
+ `{ x, y, ... }: x + y`
+
+ |
+
+
+ A function that expects a set with required attributes `x` and `y` and ignores any other attributes
+
+ |
+
+
+
+
+ `{ x, y } @ args: x + y`
+
+ `args @ { x, y }: x + y`
+
+ |
+
+
+ A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args`
+
+ |
+
+
+
+
+ *Built-in functions*
+
+ |
+
+
+
+
+ |
+
+
+
+
+ `import ./foo.nix`
+
+ |
+
+
+ Load and return Nix expression in given file
+
+ |
+
+
+
+
+ `map (x: x + x) [ 1 2 3 ]`
+
+ |
+
+
+ Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`)
+
+ |
+
+
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.
+
+
+
+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
+
+-