From 35ac16e75e1fb7c948adecd64904f40b96d1d8fb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 22 Oct 2007 12:58:28 +0000 Subject: [PATCH] * Move list of built-in functions to a separate file. --- doc/manual/Makefile.am | 2 +- doc/manual/builtins.xml | 588 +++++++++++++++++++++++++ doc/manual/writing-nix-expressions.xml | 586 +----------------------- 3 files changed, 592 insertions(+), 584 deletions(-) create mode 100644 doc/manual/builtins.xml diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index b9a6b6184..ac030ee56 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -20,7 +20,7 @@ man1_MANS = nix-env.1 nix-build.1 nix-store.1 nix-instantiate.1 \ FIGURES = figures/user-environments.png MANUAL_SRCS = manual.xml introduction.xml installation.xml \ - package-management.xml writing-nix-expressions.xml \ + package-management.xml writing-nix-expressions.xml builtins.xml \ build-farm.xml \ $(man1_MANS:.1=.xml) \ troubleshooting.xml bugs.xml opt-common.xml opt-common-syn.xml \ diff --git a/doc/manual/builtins.xml b/doc/manual/builtins.xml new file mode 100644 index 000000000..8f9272505 --- /dev/null +++ b/doc/manual/builtins.xml @@ -0,0 +1,588 @@ +
+ +Built-in functions + + +This section lists the functions and constants 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 an attribute set that contains all built-in +functions and values. For instance, derivation +is also available as builtins.derivation. + + + + + + abort s + + Abort Nix expression evaluation, print error + message s. + + + + + builtins.add + e1 e2 + + Return the sum of the integers + e1 and + e2. + + + + + builtins.attrNames + attrs + + Return the names of the attributes in the + attribute set attrs in a sorted list. + For instance, builtins.attrNames {y = 1; x = + "foo";} evaluates to ["x" "y"]. + There is no built-in function attrValues, but + you can easily define it yourself: + + +attrValues = attrs: map (name: builtins.getAttr name attrs) (builtins.attrNames attrs); + + + + + + + baseNameOf s + + Return the base name of the + string s, that is, everything following + the final slash in the string. This is similar to the GNU + basename command. + + + + + builtins + + The attribute 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., + + +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. + However, in that case you should not write + + +if builtins ? getEnv then __getEnv "PATH" else "" + + This Nix expression will trigger an “undefined variable” error on + older Nix versions since __getEnv doesn’t + exist. builtins.getEnv, on the other hand, is + safe since builtins always exists and attribute + selection is lazy, so it’s only performed if the test + succeeds. + + + + + 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 + "powerpc-darwin". + + + + + + + + + + + derivation + attrs + + derivation is described in + . + + + + + dirOf s + + Return the directory part of the string + s, that is, everything before the final + slash in the string. This is similar to the GNU + dirname command. + + + + + builtins.getAttr + s attrs + + getAttr returns the attribute + named s from the attribute set + attrs. Evaluation aborts if the + attribute doesn’t exist. This is a dynamic version of the + . operator, since s + is an expression rather than an identifier. + + + + + builtins.getEnv + s + + getEnv returns the value of + the environment variable s, or an empty + string if the variable doesn’t exist. This function should be + used with care, as it can introduce all sorts of nasty environment + dependencies in your Nix expression. + + getEnv is used in Nix Packages to + locate the file ~/.nixpkgs/config.nix, which + contains user-local settings for Nix Packages. (That is, it does + a getEnv "HOME" to locate the user’s home + directory.) + + + + + builtins.hasAttr + s attrs + + hasAttr returns + true if the attribute set + attrs has an attribute named + s, and false + otherwise. This is a dynamic version of the ? + operator, since s is an expression + rather than an identifier. + + + + + builtins.head + list + + Return the first element of a list; abort + evaluation if the argument isn’t a list or is an empty list. You + can test whether a list is empty by comparing it with + []. + + + + + import + path + + Load, parse and return the Nix expression in the + file path. Evaluation aborts if the + file doesn’t exist or contains an incorrect Nix + expression. import implements Nix’s module + system: you can put any Nix expression (such as an attribute set + or a function) in a separate file, and use it from Nix expressions + in other files. + + A Nix expression loaded by import must + not contain any free variables (identifiers + that are not defined in the Nix expression itself and are not + built-in). Therefore, it cannot refer to variables that are in + scope at the call site. For instance, if you have a calling + expression + + +rec { + x = 123; + y = import ./foo.nix; +} + + then the following foo.nix will give an + error: + + +x + 456 + + since x is not in scope in + foo.nix. If you want x + to be available in foo.nix, you should pass + it as a function argument: + + +rec { + x = 123; + y = import ./foo.nix x; +} + + and + + +x: x + 456 + + (The function argument doesn’t have to be called + x in foo.nix; any name + would work.) + + + + + builtins.isList + e + + Return true if + e evaluates to a list, and + false otherwise. + + + + + isNull + e + + Return true if + e evaluates to null, + and false otherwise. + + This function is deprecated; + just write e == null instead. + + + + + + + builtins.lessThan + e1 e2 + + Return true if the integer + e1 is less than the integer + e2, and false + otherwise. Evaluation aborts if either + e1 or e2 + does not evaluate to an integer. + + + + + map + f list + + Apply the function f to + each element in the list list. For + example, + + +map (x: "foo" + x) ["bar" "bla" "abc"] + + evaluates to ["foobar" "foobla" + "fooabc"]. + + + + + builtins.pathExists + path + + Return true if the path + path exists, and + false otherwise. One application of this + function is to conditionally include a Nix expression containing + user configuration: + + +let + fileName = builtins.getEnv "CONFIG_FILE"; + config = + if fileName != "" && builtins.pathExists (builtins.toPath fileName) + then import (builtins.toPath fileName) + else { someSetting = false; }; # default configuration +in config.someSetting + + (Note that CONFIG_FILE must be an absolute path for + this to work.) + + + + + + + + removeAttrs + attrs list + + Remove the attributes listed in + list from the attribute set + attrs. The attributes don’t have to + exist in attrs. For instance, + + +removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"] + + evaluates to {y = 2;}. + + + + + builtins.tail + list + + Return the second to last elements of a list; + abort evaluation if the argument isn’t a list or is an empty + list. + + + + + builtins.toFile + name s + + Store the string s in a + file in the Nix store and return its path. The file has suffix + name. This file can be used as an + input to derivations. One application is to write builders + “inline”. For instance, the following Nix expression combines + and into one file: + + +{stdenv, fetchurl, perl}: + +stdenv.mkDerivation { + name = "hello-2.1.1"; + + builder = builtins.toFile "builder.sh" " + source $stdenv/setup + + PATH=$perl/bin:$PATH + + tar xvfz $src + cd hello-* + ./configure --prefix=$out + make + make install + "; + + src = fetchurl { + url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz; + md5 = "70c9ccf9fac07f762c24f2df2290784d"; + }; + inherit perl; +} + + + + It is even possible for one file to refer to another, e.g., + + + builder = let + configFile = builtins.toFile "foo.conf" " + # This is some dummy configuration file. + ... + "; + in builtins.toFile "builder.sh" " + source $stdenv/setup + ... + cp ${configFile} $out/etc/foo.conf + "; + + Note that ${configFile} is an antiquotation + (see ), so the result of the + expression configFile (i.e., a path like + /nix/store/m7p7jfny445k...-foo.conf) will be + spliced into the resulting string. + + It is however not allowed to have files + mutually referring to each other, like so: + + +let + foo = builtins.toFile "foo" "...${bar}..."; + bar = builtins.toFile "bar" "...${foo}..."; +in foo + + This is not allowed because it would cause a cyclic dependency in + the computation of the cryptographic hashes for + foo and bar. + + + + + builtins.toPath s + + Convert the string value + s into a path value. The string + s must represent an absolute path + (i.e., must start with /). The path need not + exist. The resulting path is canonicalised, e.g., + builtins.toPath "//foo/xyzzy/../bar/" returns + /foo/bar. + + + + + toString e + + Convert the expression + e to a string. + e can be a string (in which case + toString is a no-op) or a path (e.g., + toString /foo/bar yields + "/foo/bar". + + + + + builtins.toXML e + + Return a string containing an XML representation + of e. The main application for + toXML is to communicate information with the + builder in a more structured format than plain environment + variables. + + + + shows an example where this is + the case. The builder is supposed to generate the configuration + file for a Jetty + servlet container. A servlet container contains a number + of servlets (*.war files) each exported under + a specific URI prefix. So the servlet configuration is a list of + attribute sets containing the path and + war of the servlet (). This kind of information is + difficult to communicate with the normal method of passing + information through an environment variable, which just + concatenates everything together into a string (which might just + work in this case, but wouldn’t work if fields are optional or + contain lists themselves). Instead the Nix expression is + converted to an XML representation with + toXML, which is unambiguous and can easily be + processed with the appropriate tools. For instance, in the + example an XSLT stylesheet () is applied to it () to + generate the XML configuration file for the Jetty server. The XML + representation produced from by toXML is shown in . + + Note that uses the toFile built-in to write the + builder and the stylesheet “inline” in the Nix expression. The + path of the stylesheet is spliced into the builder at + xsltproc ${stylesheet} + .... + + Passing information to a builder + using <function>toXML</function> + + $out/server-conf.xml]]> + + + + + + + + + + + + + "; + + servlets = builtins.toXML []]> + + + + XML representation produced by + <function>toXML</function> + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + +
diff --git a/doc/manual/writing-nix-expressions.xml b/doc/manual/writing-nix-expressions.xml index ce6c1f4ad..c4bc35cc7 100644 --- a/doc/manual/writing-nix-expressions.xml +++ b/doc/manual/writing-nix-expressions.xml @@ -1,6 +1,7 @@ + xml:id='chap-writing-nix-expressions' + xmlns:xi="http://www.w3.org/2001/XInclude"> Writing Nix Expressions @@ -1339,589 +1340,8 @@ command-line argument. See -
Built-in functions -This section lists the functions and constants 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 an attribute set that contains all built-in -functions and values. For instance, derivation -is also available as builtins.derivation. - - - - - - abort s - - Abort Nix expression evaluation, print error - message s. - - - - - builtins.add - e1 e2 - - Return the sum of the integers - e1 and - e2. - - - - - builtins.attrNames - attrs - - Return the names of the attributes in the - attribute set attrs in a sorted list. - For instance, builtins.attrNames {y = 1; x = - "foo";} evaluates to ["x" "y"]. - There is no built-in function attrValues, but - you can easily define it yourself: - - -attrValues = attrs: map (name: builtins.getAttr name attrs) (builtins.attrNames attrs); - - - - - - - baseNameOf s - - Return the base name of the - string s, that is, everything following - the final slash in the string. This is similar to the GNU - basename command. - - - - - builtins - - The attribute 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., - - -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. - However, in that case you should not write - - -if builtins ? getEnv then __getEnv "PATH" else "" - - This Nix expression will trigger an “undefined variable” error on - older Nix versions since __getEnv doesn’t - exist. builtins.getEnv, on the other hand, is - safe since builtins always exists and attribute - selection is lazy, so it’s only performed if the test - succeeds. - - - - - 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 - "powerpc-darwin". - - - - - - - - - - - derivation - attrs - - derivation is described in - . - - - - - dirOf s - - Return the directory part of the string - s, that is, everything before the final - slash in the string. This is similar to the GNU - dirname command. - - - - - builtins.getAttr - s attrs - - getAttr returns the attribute - named s from the attribute set - attrs. Evaluation aborts if the - attribute doesn’t exist. This is a dynamic version of the - . operator, since s - is an expression rather than an identifier. - - - - - builtins.getEnv - s - - getEnv returns the value of - the environment variable s, or an empty - string if the variable doesn’t exist. This function should be - used with care, as it can introduce all sorts of nasty environment - dependencies in your Nix expression. - - getEnv is used in Nix Packages to - locate the file ~/.nixpkgs/config.nix, which - contains user-local settings for Nix Packages. (That is, it does - a getEnv "HOME" to locate the user’s home - directory.) - - - - - builtins.hasAttr - s attrs - - hasAttr returns - true if the attribute set - attrs has an attribute named - s, and false - otherwise. This is a dynamic version of the ? - operator, since s is an expression - rather than an identifier. - - - - - builtins.head - list - - Return the first element of a list; abort - evaluation if the argument isn’t a list or is an empty list. You - can test whether a list is empty by comparing it with - []. - - - - - import - path - - Load, parse and return the Nix expression in the - file path. Evaluation aborts if the - file doesn’t exist or contains an incorrect Nix - expression. import implements Nix’s module - system: you can put any Nix expression (such as an attribute set - or a function) in a separate file, and use it from Nix expressions - in other files. - - A Nix expression loaded by import must - not contain any free variables (identifiers - that are not defined in the Nix expression itself and are not - built-in). Therefore, it cannot refer to variables that are in - scope at the call site. For instance, if you have a calling - expression - - -rec { - x = 123; - y = import ./foo.nix; -} - - then the following foo.nix will give an - error: - - -x + 456 - - since x is not in scope in - foo.nix. If you want x - to be available in foo.nix, you should pass - it as a function argument: - - -rec { - x = 123; - y = import ./foo.nix x; -} - - and - - -x: x + 456 - - (The function argument doesn’t have to be called - x in foo.nix; any name - would work.) - - - - - builtins.isList - e - - Return true if - e evaluates to a list, and - false otherwise. - - - - - isNull - e - - Return true if - e evaluates to null, - and false otherwise. - - This function is deprecated; - just write e == null instead. - - - - - - - builtins.lessThan - e1 e2 - - Return true if the integer - e1 is less than the integer - e2, and false - otherwise. Evaluation aborts if either - e1 or e2 - does not evaluate to an integer. - - - - - map - f list - - Apply the function f to - each element in the list list. For - example, - - -map (x: "foo" + x) ["bar" "bla" "abc"] - - evaluates to ["foobar" "foobla" - "fooabc"]. - - - - - builtins.pathExists - path - - Return true if the path - path exists, and - false otherwise. One application of this - function is to conditionally include a Nix expression containing - user configuration: - - -let - fileName = builtins.getEnv "CONFIG_FILE"; - config = - if fileName != "" && builtins.pathExists (builtins.toPath fileName) - then import (builtins.toPath fileName) - else { someSetting = false; }; # default configuration -in config.someSetting - - (Note that CONFIG_FILE must be an absolute path for - this to work.) - - - - - - - - removeAttrs - attrs list - - Remove the attributes listed in - list from the attribute set - attrs. The attributes don’t have to - exist in attrs. For instance, - - -removeAttrs { x = 1; y = 2; z = 3; } ["a" "x" "z"] - - evaluates to {y = 2;}. - - - - - builtins.tail - list - - Return the second to last elements of a list; - abort evaluation if the argument isn’t a list or is an empty - list. - - - - - builtins.toFile - name s - - Store the string s in a - file in the Nix store and return its path. The file has suffix - name. This file can be used as an - input to derivations. One application is to write builders - “inline”. For instance, the following Nix expression combines - and into one file: - - -{stdenv, fetchurl, perl}: - -stdenv.mkDerivation { - name = "hello-2.1.1"; - - builder = builtins.toFile "builder.sh" " - source $stdenv/setup - - PATH=$perl/bin:$PATH - - tar xvfz $src - cd hello-* - ./configure --prefix=$out - make - make install - "; - - src = fetchurl { - url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz; - md5 = "70c9ccf9fac07f762c24f2df2290784d"; - }; - inherit perl; -} - - - - It is even possible for one file to refer to another, e.g., - - - builder = let - configFile = builtins.toFile "foo.conf" " - # This is some dummy configuration file. - ... - "; - in builtins.toFile "builder.sh" " - source $stdenv/setup - ... - cp ${configFile} $out/etc/foo.conf - "; - - Note that ${configFile} is an antiquotation - (see ), so the result of the - expression configFile (i.e., a path like - /nix/store/m7p7jfny445k...-foo.conf) will be - spliced into the resulting string. - - It is however not allowed to have files - mutually referring to each other, like so: - - -let - foo = builtins.toFile "foo" "...${bar}..."; - bar = builtins.toFile "bar" "...${foo}..."; -in foo - - This is not allowed because it would cause a cyclic dependency in - the computation of the cryptographic hashes for - foo and bar. - - - - - builtins.toPath s - - Convert the string value - s into a path value. The string - s must represent an absolute path - (i.e., must start with /). The path need not - exist. The resulting path is canonicalised, e.g., - builtins.toPath "//foo/xyzzy/../bar/" returns - /foo/bar. - - - - - toString e - - Convert the expression - e to a string. - e can be a string (in which case - toString is a no-op) or a path (e.g., - toString /foo/bar yields - "/foo/bar". - - - - - builtins.toXML e - - Return a string containing an XML representation - of e. The main application for - toXML is to communicate information with the - builder in a more structured format than plain environment - variables. - - - - shows an example where this is - the case. The builder is supposed to generate the configuration - file for a Jetty - servlet container. A servlet container contains a number - of servlets (*.war files) each exported under - a specific URI prefix. So the servlet configuration is a list of - attribute sets containing the path and - war of the servlet (). This kind of information is - difficult to communicate with the normal method of passing - information through an environment variable, which just - concatenates everything together into a string (which might just - work in this case, but wouldn’t work if fields are optional or - contain lists themselves). Instead the Nix expression is - converted to an XML representation with - toXML, which is unambiguous and can easily be - processed with the appropriate tools. For instance, in the - example an XSLT stylesheet () is applied to it () to - generate the XML configuration file for the Jetty server. The XML - representation produced from by toXML is shown in . - - Note that uses the toFile built-in to write the - builder and the stylesheet “inline” in the Nix expression. The - path of the stylesheet is spliced into the builder at - xsltproc ${stylesheet} - .... - - Passing information to a builder - using <function>toXML</function> - - $out/server-conf.xml]]> - - - - - - - - - - - - - "; - - servlets = builtins.toXML []]> - - - - XML representation produced by - <function>toXML</function> - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - - - - - - -
+