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 construct is called interpolated string, and the expression inside is an interpolated expression.
Syntax
interpolation_element →
${
expression}
Examples
String
Rather than writing
"--with-freetype2-library=" + freetype + "/lib"
(where freetype
is a derivation), you can instead write
"--with-freetype2-library=${freetype}/lib"
The latter is automatically translated to the former.
A more complicated example (from the Nix expression for Qt):
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}
).
To write a literal ${
in an regular string, escape it with a backslash (\
).
Example
"echo \${PATH}"
"echo ${PATH}"
To write a literal ${
in an indented string, escape it with two single quotes (''
).
Example
'' echo ''${PATH} ''
"echo ${PATH}\n"
$${
can be written literally in any string.
Example
In Make,
$
in file names or recipes is represented as$$
, see GNUmake
: Basics of Variable Reference. This can be expressed directly in the Nix language strings:'' MAKEVAR = Hello all: @export BASHVAR=world; echo $(MAKEVAR) $${BASHVAR} ''
"MAKEVAR = Hello\nall:\n\t@export BASHVAR=world; echo $(MAKEVAR) $\${BASHVAR}\n"
See the documentation on strings for details.
Path
Rather than writing
./. + "/" + foo + "-" + bar + ".nix"
or
./. + "/${foo}-${bar}.nix"
you can instead write
./${foo}-${bar}.nix
Attribute name
Attribute names can be interpolated strings.
Example
let name = "foo"; in { ${name} = 123; }
{ foo = 123; }
Attributes can be selected with interpolated strings.
Example
let name = "foo"; in { foo = 123; }.${name}
123
Interpolated expression
An expression that is interpolated must evaluate to one of the following:
-
a string
-
a path
-
an attribute set that has a
__toString
attribute or anoutPath
attribute__toString
must be a function that takes the attribute set itself and returns a stringoutPath
must be a string
This includes derivations or flake inputs (experimental).
A string interpolates to itself.
A path in an interpolated expression is first copied into the Nix store, and the resulting string is the store path of the newly created store object.
Example
$ mkdir foo
Reference the empty directory in an interpolated expression:
"${./foo}"
"/nix/store/2hhl2nz5v0khbn06ys82nrk99aa1xxdw-foo"
A derivation interpolates to the store path of its first output.
Example
let pkgs = import <nixpkgs> {}; in "${pkgs.hello}"
"/nix/store/4xpfqf29z4m8vbhrqcz064wfmb46w5r7-hello-2.12.1"
An attribute set interpolates to the return value of the function in the __toString
applied to the attribute set itself.
Example
let a = { value = 1; __toString = self: toString (self.value + 1); }; in "${a}"
"2"
An attribute set also interpolates to the value of its outPath
attribute.
Example
let a = { outPath = "foo"; }; in "${a}"
"foo"
If both __toString
and outPath
are present in an attribute set, __toString
takes precedence.
Example
let a = { __toString = _: "yes"; outPath = throw "no"; }; in "${a}"
"yes"
If neither is present, an error is thrown.
Example
let a = {}; in "${a}"
error: cannot coerce a set to a string: { } at «string»:4:2: 3| in 4| "${a}" | ^