aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/src/language
diff options
context:
space:
mode:
authorValentin Gagarin <valentin.gagarin@tweag.io>2022-11-09 00:31:48 +0100
committerValentin Gagarin <valentin.gagarin@tweag.io>2023-01-02 14:38:57 +0100
commite0c4a95611db4fde942b4e3ee4b6f8e07f956248 (patch)
tree0ee8988c7ab8215484d293546de0c830367b9a73 /doc/manual/src/language
parent80a0f77e49817a0fdb67109f2a7c3afb2c4e7d9d (diff)
antiquotation -> string interpolation
as proposed by @mkaito[1] and @tazjin[2] and discussed with @edolstra and Nix maintainers [1]: https://github.com/NixOS/nix.dev/pull/267#issuecomment-1270076332 [2]: https://github.com/NixOS/nix.dev/pull/267#issuecomment-1270201979 Co-authored-by: John Ericson <git@JohnEricson.me> Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
Diffstat (limited to 'doc/manual/src/language')
-rw-r--r--doc/manual/src/language/string-interpolation.md82
-rw-r--r--doc/manual/src/language/values.md103
2 files changed, 121 insertions, 64 deletions
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
index 6fc8c0369..08baa8f95 100644
--- a/doc/manual/src/language/values.md
+++ b/doc/manual/src/language/values.md
@@ -13,41 +13,9 @@
returns and tabs can be written as `\n`, `\r` and `\t`,
respectively.
- You can include the result of an expression into a string by
- enclosing it in `${...}`, a feature known as *antiquotation*. The
- enclosed expression must evaluate to something that can be coerced
- into a string (meaning that it must be a string, a path, or a
- derivation). For instance, rather than writing
+ You can include the results of other expressions into a string by enclosing them in `${ }`, a feature known as [string interpolation].
- ```nix
- "--with-freetype2-library=" + freetype + "/lib"
- ```
-
- (where `freetype` is a derivation), you can instead write the more
- natural
-
- ```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 antiquotations that
- themselves contain strings (e.g., `"-thread"`), some of which in
- turn contain expressions (e.g., `${mesa}`).
+ [string interpolation]: ./string-interpolation.md
The second way to write string literals is as an *indented string*,
which is enclosed between pairs of *double single-quotes*, like so:
@@ -75,7 +43,7 @@
Note that the whitespace and newline following the opening `''` is
ignored if there is no non-whitespace text on the initial line.
- Antiquotation (`${expr}`) is supported in indented strings.
+ Indented strings support [string interpolation].
Since `${` and `''` have special meaning in indented strings, you
need a way to quote them. `$` can be escaped by prefixing it with
@@ -143,26 +111,23 @@
environment variable `NIX_PATH` will be searched for the given file
or directory name.
- Antiquotation is supported in any paths except those in angle brackets.
- `./${foo}-${bar}.nix` is a more convenient way of writing
- `./. + "/" + foo + "-" + bar + ".nix"` or `./. + "/${foo}-${bar}.nix"`. At
- least one slash must appear *before* any antiquotations for this to be
- recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division
- operation. `./a.${foo}/b.${bar}` is a path.
-
- When a path appears in an antiquotation, and is thus coerced into a string,
- the path is first copied into the Nix store and the resulting string is
- the Nix store path. For instance `"${./foo.txt}" will cause `foo.txt` in
- the current directory to be copied into the Nix store and result in the
- string `"/nix/store/<HASH>-foo.txt"`.
-
- Note that the Nix language assumes that all input files will remain
- _unchanged_ during the course of the Nix expression evaluation.
- If you for example antiquote a file path during a `nix repl` session, and
- then later in the same session, after having changed the file contents,
- evaluate the antiquotation with the file path again, then Nix will still
- return the first store path. It will _not_ reread the file contents to
- produce a different Nix store path.
+ When an [interpolated string][string interpolation] evaluates to a path, the path is first copied into the Nix store and the resulting string is the [store path] of the newly created [store object].
+
+ [store path]: ../glossary.md#gloss-store-path
+ [store object]: ../glossary.md#gloss-store-object
+
+ For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` in the current directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.
+
+ Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
+ For example, assume you used a file path in an interpolated string during a `nix repl` session.
+ Later in the same session, after having changed the file contents, evaluating the interpolated string with the file path again might not return a new store path, since Nix might not re-read the file contents.
+
+ Paths themselves, except those in angle brackets (`< >`), support [string interpolation].
+
+ At least one slash (`/`) must appear *before* any interpolated expression for the result to be recognized as a path.
+
+ `a.${foo}/b.${bar}` is a syntactically valid division operation.
+ `./a.${foo}/b.${bar}` is a path.
- <a id="type-boolean" href="#type-boolean">Boolean</a>
@@ -235,23 +200,33 @@ will evaluate to `"Xyzzy"` because there is no `c` attribute in the set.
You can use arbitrary double-quoted strings as attribute names:
```nix
-{ "foo ${bar}" = 123; "nix-1.0" = 456; }."foo ${bar}"
+{ "$!@#?" = 123; }."$!@#?"
+```
+
+```nix
+let bar = "bar";
+{ "foo ${bar}" = 123; }."foo ${bar}"
```
-This will evaluate to `123` (Assuming `bar` is antiquotable). In the
-case where an attribute name is just a single antiquotation, the quotes
-can be dropped:
+Both will evaluate to `123`.
+
+Attribute names support [string interpolation]:
+
+```nix
+let bar = "foo"; in
+{ foo = 123; }.${bar}
+```
```nix
-{ foo = 123; }.${bar} or 456
+let bar = "foo"; in
+{ ${bar} = 123; }.foo
```
-This will evaluate to `123` if `bar` evaluates to `"foo"` when coerced
-to a string and `456` otherwise (again assuming `bar` is antiquotable).
+Both will evaluate to `123`.
In the special case where an attribute name inside of a set declaration
-evaluates to `null` (which is normally an error, as `null` is not
-antiquotable), that attribute is simply not added to the set:
+evaluates to `null` (which is normally an error, as `null` cannot be coerced to
+a string), that attribute is simply not added to the set:
```nix
{ ${if foo then "bar" else null} = true; }