about summary refs log tree commit diff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/manual/writing-nix-expressions.xml104
1 files changed, 73 insertions, 31 deletions
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml
index 53b5f06a8ad8..aca5c7c6ca4f 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -937,51 +937,93 @@ set.</para>
 <para>Functions have the following form:
 
 <programlisting>
-{<replaceable>params</replaceable>}: <replaceable>body</replaceable></programlisting>
-
-This defines a function that must be called with an attribute set
-containing the attributes listed in <replaceable>params</replaceable>,
-which is a comma-separated list of attribute names.  Optionally, for
-each parameter a <emphasis>default value</emphasis> may be specified
-by writing <literal><replaceable>param</replaceable> ?
-<replaceable>e</replaceable></literal>, where
-<replaceable>e</replaceable> is an arbitrary expression.  If a
-parameter has a default, the corresponding attribute may be omitted in
-function calls.</para>
+<replaceable>pattern</replaceable>: <replaceable>body</replaceable></programlisting>
 
-<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.,
+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>An <emphasis>attribute set pattern</emphasis> of the
+  form <literal>{name1, name2, …, nameN}</literal>
+  matches an attribute set containing the listed attributes, and binds
+  the values of those attributes to variables in the function body.
+  For example, the function
 
 <programlisting>
-let concat = {x, y}: x + y;
-in concat {x = "foo"; y = "bar";}</programlisting>
+{x, y, z}: z + y + x</programlisting>
 
-</para>
+  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>): 
 
-<para>It is also possible to define a function that takes a single
-argument and that does not need to be called with an attribute set as
-argument.  The syntax is
+<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><replaceable>name</replaceable> ?
+  <replaceable>e</replaceable></literal>, where
+  <replaceable>e</replaceable> is an arbitrary expression.  For example,
 
 <programlisting>
-<replaceable>var</replaceable>: <replaceable>body</replaceable></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>
+
 
-where <replaceable>var</replaceable> is the name of the argument.  It
-is not possible to define a default.  Example:
+  <listitem><para>An <literal>@</literal>-pattern requires that the
+  argument matches with the patterns on the left- and right-hand side
+  of the <literal>@</literal>-sign.  For example:
 
 <programlisting>
-let negate = x: !x;
-    concat = x: y: x + y;
-in if negate true then concat "foo" "bar" else ""</programlisting>
+args@{x, y, z, ...}: z + y + x + args.a</programlisting>
+
+  Here <varname>args</varname> is bound to the entire argument, which
+  is further matches against the pattern <literal>{x, y, z,
+  ...}</literal>.</para></listitem>
 
-Note that <function>concat</function> is a function that takes one
-arguments 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.,
+
+</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>
-map (concat "foo") ["bar" "bla" "abc"]</programlisting>
+let concat = {x, y}: x + y;
+in concat {x = "foo"; y = "bar";}</programlisting>
 
-evaluates to <literal>["foobar" "foobla" "fooabc"]</literal>.</para>
+</para>
 
 </simplesect>