diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml index 53b5f06a8..aca5c7c6c 100644 --- a/doc/manual/writing-nix-expressions.xml +++ b/doc/manual/writing-nix-expressions.xml @@ -937,17 +937,84 @@ set. Functions have the following form: -{params}: body +pattern: body -This defines a function that must be called with an attribute set -containing the attributes listed in params, -which is a comma-separated list of attribute names. Optionally, for -each parameter a default value may be specified -by writing param ? -e, where -e is an arbitrary expression. If a -parameter has a default, the corresponding attribute may be omitted in -function calls. +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"]. + + + An attribute set pattern of the + form {name1, name2, …, nameN} + 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 + + +{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 requires that the + argument matches with the patterns on the left- and right-hand side + of the @-sign. For example: + + +args@{x, y, z, ...}: z + y + x + args.a + + Here args is bound to the entire argument, which + is further matches against the pattern {x, y, z, + ...}. + + + Note that functions do not have names. If you want to give them a name, you can bind them to an attribute, e.g., @@ -958,31 +1025,6 @@ in concat {x = "foo"; y = "bar";} -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 - - -var: body - -where var is the name of the argument. It -is not possible to define a default. 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 -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., - - -map (concat "foo") ["bar" "bla" "abc"] - -evaluates to ["foobar" "foobla" "fooabc"]. -