aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/expressions/language-constructs.xml
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-07-24 15:48:40 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-07-24 15:48:40 +0200
commit1308c8404e19aacc6458b3813d445857620a60a8 (patch)
tree78f64ccd6f05b29991e74fccfa1d9d22bfaa91b2 /doc/manual/expressions/language-constructs.xml
parent05a282295f3d454c811f9bdd9b755f6a5c07c190 (diff)
Remove DocBook manual
Diffstat (limited to 'doc/manual/expressions/language-constructs.xml')
-rw-r--r--doc/manual/expressions/language-constructs.xml408
1 files changed, 0 insertions, 408 deletions
diff --git a/doc/manual/expressions/language-constructs.xml b/doc/manual/expressions/language-constructs.xml
deleted file mode 100644
index e1c589f61..000000000
--- a/doc/manual/expressions/language-constructs.xml
+++ /dev/null
@@ -1,408 +0,0 @@
-<section xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- version="5.0"
- xml:id="sec-constructs">
-
-<title>Language Constructs</title>
-
-<section><title>Recursive sets</title>
-
-<para>Recursive sets are just normal sets, but the attributes can
-refer to each other. For example,
-
-<programlisting>
-rec {
- x = y;
- y = 123;
-}.x
-</programlisting>
-
-evaluates to <literal>123</literal>. Note that without
-<literal>rec</literal> the binding <literal>x = y;</literal> would
-refer to the variable <varname>y</varname> 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.</para>
-
-<para>Recursive sets of course introduce the danger of infinite
-recursion. For example, the expression
-
-<programlisting>
-rec {
- x = y;
- y = x;
-}.x</programlisting>
-
-will crash with an <literal>infinite recursion encountered</literal>
-error message.</para>
-
-</section>
-
-
-<section xml:id="sect-let-expressions"><title>Let-expressions</title>
-
-<para>A let-expression allows you to define local variables for an
-expression. For instance,
-
-<programlisting>
-let
- x = "foo";
- y = "bar";
-in x + y</programlisting>
-
-evaluates to <literal>"foobar"</literal>.
-
-</para>
-
-</section>
-
-
-<section><title>Inheriting attributes</title>
-
-<para>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
-<literal>inherit</literal> keyword. For instance,
-
-<programlisting>
-let x = 123; in
-{ inherit x;
- y = 456;
-}</programlisting>
-
-is equivalent to
-
-<programlisting>
-let x = 123; in
-{ x = x;
- y = 456;
-}</programlisting>
-
-and both evaluate to <literal>{ x = 123; y = 456; }</literal>. (Note that
-this works because <varname>x</varname> is added to the lexical scope
-by the <literal>let</literal> construct.) It is also possible to
-inherit attributes from another set. For instance, in this fragment
-from <filename>all-packages.nix</filename>,
-
-<programlisting>
- graphviz = (import ../tools/graphics/graphviz) {
- inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
- inherit (xlibs) libXaw;
- };
-
- xlibs = {
- libX11 = ...;
- libXaw = ...;
- ...
- }
-
- libpng = ...;
- libjpg = ...;
- ...</programlisting>
-
-the set used in the function call to the function defined in
-<filename>../tools/graphics/graphviz</filename> inherits a number of
-variables from the surrounding scope (<varname>fetchurl</varname>
-... <varname>yacc</varname>), but also inherits
-<varname>libXaw</varname> (the X Athena Widgets) from the
-<varname>xlibs</varname> (X11 client-side libraries) set.</para>
-
-<para>
-Summarizing the fragment
-
-<programlisting>
-...
-inherit x y z;
-inherit (src-set) a b c;
-...</programlisting>
-
-is equivalent to
-
-<programlisting>
-...
-x = x; y = y; z = z;
-a = src-set.a; b = src-set.b; c = src-set.c;
-...</programlisting>
-
-when used while defining local variables in a let-expression or
-while defining a set.</para>
-
-</section>
-
-
-<section xml:id="ss-functions"><title>Functions</title>
-
-<para>Functions have the following form:
-
-<programlisting>
-<emphasis>pattern</emphasis>: <emphasis>body</emphasis></programlisting>
-
-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:</para>
-
-<itemizedlist>
-
-
- <listitem><para>If a pattern is a single identifier, then the
- function matches any argument. Example:
-
- <programlisting>
-let negate = x: !x;
- concat = x: y: x + y;
-in if negate true then concat "foo" "bar" else ""</programlisting>
-
- Note that <function>concat</function> 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.,
-
- <programlisting>
-map (concat "foo") [ "bar" "bla" "abc" ]</programlisting>
-
- evaluates to <literal>[ "foobar" "foobla"
- "fooabc" ]</literal>.</para></listitem>
-
-
- <listitem><para>A <emphasis>set pattern</emphasis> of the form
- <literal>{ name1, name2, …, nameN }</literal> matches a set
- containing the listed attributes, and binds the values of those
- attributes to variables in the function body. For example, the
- function
-
-<programlisting>
-{ x, y, z }: z + y + x</programlisting>
-
- can only be called with a set containing exactly the attributes
- <varname>x</varname>, <varname>y</varname> and
- <varname>z</varname>. No other attributes are allowed. If you want
- to allow additional arguments, you can use an ellipsis
- (<literal>...</literal>):
-
-<programlisting>
-{ x, y, z, ... }: z + y + x</programlisting>
-
- This works on any set that contains at least the three named
- attributes.</para>
-
- <para>It is possible to provide <emphasis>default values</emphasis>
- for attributes, in which case they are allowed to be missing. A
- default value is specified by writing
- <literal><emphasis>name</emphasis> ?
- <emphasis>e</emphasis></literal>, where
- <emphasis>e</emphasis> is an arbitrary expression. For example,
-
-<programlisting>
-{ x, y ? "foo", z ? "bar" }: z + y + x</programlisting>
-
- specifies a function that only requires an attribute named
- <varname>x</varname>, but optionally accepts <varname>y</varname>
- and <varname>z</varname>.</para></listitem>
-
-
- <listitem><para>An <literal>@</literal>-pattern provides a means of referring
- to the whole value being matched:
-
-<programlisting> args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
-
-but can also be written as:
-
-<programlisting> { x, y, z, ... } @ args: z + y + x + args.a</programlisting>
-
- Here <varname>args</varname> is bound to the entire argument, which
- is further matched against the pattern <literal>{ x, y, z,
- ... }</literal>. <literal>@</literal>-pattern makes mainly sense with an
- ellipsis(<literal>...</literal>) as you can access attribute names as
- <literal>a</literal>, using <literal>args.a</literal>, which was given as an
- additional attribute to the function.
- </para>
-
- <warning>
- <para>
- The <literal>args@</literal> 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 <literal>args</literal>.
- </para>
- <para>
- For instance
-<programlisting>
-let
- function = args@{ a ? 23, ... }: args;
-in
- function {}
-</programlisting>
- will evaluate to an empty attribute set.
- </para>
- </warning></listitem>
-
-</itemizedlist>
-
-<para>Note that functions do not have names. If you want to give them
-a name, you can bind them to an attribute, e.g.,
-
-<programlisting>
-let concat = { x, y }: x + y;
-in concat { x = "foo"; y = "bar"; }</programlisting>
-
-</para>
-
-</section>
-
-
-<section><title>Conditionals</title>
-
-<para>Conditionals look like this:
-
-<programlisting>
-if <emphasis>e1</emphasis> then <emphasis>e2</emphasis> else <emphasis>e3</emphasis></programlisting>
-
-where <emphasis>e1</emphasis> is an expression that should
-evaluate to a Boolean value (<literal>true</literal> or
-<literal>false</literal>).</para>
-
-</section>
-
-
-<section><title>Assertions</title>
-
-<para>Assertions are generally used to check that certain requirements
-on or between features and dependencies hold. They look like this:
-
-<programlisting>
-assert <emphasis>e1</emphasis>; <emphasis>e2</emphasis></programlisting>
-
-where <emphasis>e1</emphasis> is an expression that should
-evaluate to a Boolean value. If it evaluates to
-<literal>true</literal>, <emphasis>e2</emphasis> is returned;
-otherwise expression evaluation is aborted and a backtrace is printed.</para>
-
-<para>Here is a Nix expression for the Subversion package that shows
-how assertions can be used:.</para>
-
-<programlisting>
-{ 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 &amp;&amp; httpd.expat == expat; ②
-assert sslSupport -> openssl != null &amp;&amp; (httpServer -> httpd.openssl == openssl); ③
-assert pythonBindings -> swig != null &amp;&amp; swig.pythonSupport;
-assert javaSwigBindings -> swig != null &amp;&amp; swig.javaSupport;
-assert javahlBindings -> j2sdk != null;
-
-stdenv.mkDerivation {
- name = "subversion-1.1.1";
- ...
- openssl = if sslSupport then openssl else null; ④
- ...
-}</programlisting>
-
-<para>The points of interest are:</para>
-
-<orderedlist>
-
- <listitem>
- <para>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
- <varname>localServer</varname> argument set to
- <literal>true</literal> but the <varname>db4</varname> argument
- set to <literal>null</literal>, then the evaluation fails.</para>
- </listitem>
-
- <listitem>
- <para>This is a more subtle condition: if Subversion is built with
- Apache (<literal>httpServer</literal>) 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.</para>
- </listitem>
-
- <listitem>
- <para>This assertion says that in order for Subversion to have SSL
- support (so that it can access <literal>https</literal> URLs), an
- OpenSSL library must be passed. Additionally, it says that
- <emphasis>if</emphasis> 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.)</para>
- </listitem>
-
- <listitem>
- <para>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-<literal>null</literal> value was passed.
- This prevents an unnecessary rebuild of Subversion if OpenSSL
- changes.</para>
- </listitem>
-
-</orderedlist>
-
-</section>
-
-
-
-<section><title>With-expressions</title>
-
-<para>A <emphasis>with-expression</emphasis>,
-
-<programlisting>
-with <emphasis>e1</emphasis>; <emphasis>e2</emphasis></programlisting>
-
-introduces the set <emphasis>e1</emphasis> into the lexical
-scope of the expression <emphasis>e2</emphasis>. For instance,
-
-<programlisting>
-let as = { x = "foo"; y = "bar"; };
-in with as; x + y</programlisting>
-
-evaluates to <literal>"foobar"</literal> since the
-<literal>with</literal> adds the <varname>x</varname> and
-<varname>y</varname> attributes of <varname>as</varname> to the
-lexical scope in the expression <literal>x + y</literal>. The most
-common use of <literal>with</literal> is in conjunction with the
-<function>import</function> function. E.g.,
-
-<programlisting>
-with (import ./definitions.nix); ...</programlisting>
-
-makes all attributes defined in the file
-<filename>definitions.nix</filename> available as if they were defined
-locally in a <literal>let</literal>-expression.</para>
-
-<para>The bindings introduced by <literal>with</literal> do not shadow bindings
-introduced by other means, e.g.
-
-<programlisting>
-let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...</programlisting>
-
-establishes the same scope as
-
-<programlisting>
-let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...</programlisting>
-
-</para>
-
-</section>
-
-
-<section><title>Comments</title>
-
-<para>Comments can be single-line, started with a <literal>#</literal>
-character, or inline/multi-line, enclosed within <literal>/*
-... */</literal>.</para>
-
-</section>
-
-
-</section>