This commit is contained in:
Amy de Buitléir 2025-10-12 15:59:19 +01:00
parent d0be400f85
commit 96f65dd5a5
11 changed files with 102 additions and 7 deletions

View file

@ -4,6 +4,7 @@ The conditional construct in Nix is an _expression_, not a _statement_.
Since expressions must have values in all cases, you must specify both the `then` and the `else` branch.
[source]
.Example
....
nix-repl> a = 7

View file

@ -3,6 +3,7 @@
A `let` expression defines a value with a local scope.
[source]
.Example
....
nix-repl> let x = 3; in x*x
9
@ -15,6 +16,7 @@ You can also nest `let` expressions.
The previous expression is equivalent to the following.
[source]
.Example
....
nix-repl> let x = 3; in let y = 2; in x*x + y
11
@ -25,6 +27,7 @@ nix-repl> let x = 3; in let y = 2; in x*x + y
A variable defined inside a `let` expression will "shadow" an outer variable with the same name.
[source]
.Example
....
nix-repl> x = 100
@ -40,6 +43,7 @@ A variable in a let expression can refer to another variable in the expression.
This is similar to how recursive attribute sets work.
[source]
.Example
....
nix-repl> let x = 3; y = x + 1; in x*y
12

View file

@ -5,6 +5,7 @@
Lists can be concatenated using the `++` operator.
[source]
.Example
....
nix-repl> [ 1 2 3 ] ++ [ "apple" "banana" ]
[ 1 2 3 "apple" "banana" ]
@ -20,6 +21,7 @@ For more information on these and other built-in functions, see the Nix Manual
Testing if an element appears in a list.
[source]
.Example
....
nix-repl> fruit = [ "apple" "banana" "cantaloupe" ]
@ -34,6 +36,7 @@ Selecting an item from a list by index.
The first element in a list has index `0`.
[source]
.Example
....
nix-repl> builtins.elemAt fruit 0
"apple"
@ -45,6 +48,7 @@ nix-repl> builtins.elemAt fruit 2
Determining the number of elements in a list.
[source]
.Example
....
nix-repl> builtins.length fruit
3
@ -53,6 +57,7 @@ nix-repl> builtins.length fruit
Accessing the first element of a list.
[source]
.Example
....
nix-repl> builtins.head fruit
"apple"
@ -61,6 +66,7 @@ nix-repl> builtins.head fruit
Dropping the first element of a list.
[source]
.Example
....
nix-repl> builtins.tail fruit
[ "banana" "cantaloupe" ]
@ -73,6 +79,7 @@ but the following examples should be somewhat self-explanatory.
Using a function to filter (select elements from) a list.
[source]
.Example
....
nix-repl> numbers = [ 1 3 6 8 9 15 25 ]
@ -85,6 +92,7 @@ nix-repl> builtins.filter isBig numbers # get just the "big" numbers
Applying a function to all the elements in a list.
[source]
.Example
....
nix-repl> double = n: 2*n # multiply by two

View file

@ -5,6 +5,7 @@
The usual arithmetic operators are provided.
[source]
.Example
....
nix-repl> 1 + 2 # addition
3
@ -29,6 +30,7 @@ you can get unexpected results when you omit spaces around operators.
Consider the following example.
[source]
.Example
....
nix-repl> 6/2
/home/amy/codeberg/nix-book/6/2
@ -38,13 +40,14 @@ What happened?
Let's use the `:t` command to find out the type of the expression.
[source]
.Example
....
nix-repl> :t 6/2
a path
....
If an expression can be interpreted as a path, Nix will do so.
This is useful, because paths are _far_ more commonly used in Nix expressions
This is useful, because paths are _far_ more commonly used in Nix expressions
than arithmetic operators.
In this case, Nix interpreted `6/2` as a relative path from the current directory,
which in the above example was `/home/amy/codeberg/nix-book`.
@ -52,6 +55,7 @@ which in the above example was `/home/amy/codeberg/nix-book`.
Adding a space after the `/` operator produces the expected result.
[source]
.Example
....
nix-repl> 6/ 2
3
@ -66,6 +70,7 @@ Numbers without a decimal point are assumed to be integers.
To ensure that a number is interpreted as a floating-point value, add a decimal point.
[source]
.Example
....
nix-repl> :t 5
an integer
@ -81,6 +86,7 @@ In the example below, the first expression results in integer division (rounding
while the second produces a floating-point result.
[source]
.Example
....
nix-repl> 5 / 3
1

View file

@ -6,6 +6,7 @@ To refer to a file or directory relative to the current directory, prefix it wit
You can specify the current directory as `./.`
[source]
.Example
....
nix-repl> ./file.txt
/home/amy/codeberg/nix-book/file.txt
@ -19,6 +20,7 @@ nix-repl> ./.
Paths can be concatenated to produce a new path.
[source]
.Example
....
nix-repl> /home/wombat + /bin/sh
/home/wombat/bin/sh
@ -33,6 +35,7 @@ Relative paths are made absolute when they are parsed, which occurs before conca
This is why the result in the example below is not `/home/wombat/file.txt`.
[source]
.Example
....
nix-repl> /home/wombat + ./file.txt
/home/wombat/home/amy/codeberg/nix-book/file.txt
@ -44,6 +47,7 @@ nix-repl> /home/wombat + ./file.txt
A path can be concatenated with a string to produce a new path.
[source]
.Example
....
nix-repl> /home/wombat + "/file.txt"
/home/wombat/file.txt
@ -61,22 +65,28 @@ for more information see https://nixos.org/manual/nix/stable/language/operators#
== Concatenating a string + a path
[IMPORTANT]
====
Strings can be concatenated with paths, but with a side-effect that may surprise you:
if the path exists, the file is copied to the Nix store!
The result is a string, not a path.
====
In the example below, the file `file.txt` is copied to `/nix/store/gp8ba25gpwvbqizqfr58jr014gmv1hd8-file.txt`
(not, as you might expect, to `/home/wombat/nix/store/gp8ba25gpwvbqizqfr58jr014gmv1hd8-file.txt`).
In the example below, you might expect the result to be `"home/wombat/file.nix"`.
However, the file `file.txt` is copied to `/nix/store/gp8ba25gpwvbqizqfr58jr014gmv1hd8-file.txt`
before concatenating it to the string.
[source]
.Example
....
nix-repl> "/home/wombat" + ./file.txt
"/home/wombat/nix/store/gp8ba25gpwvbqizqfr58jr014gmv1hd8-file.txt"
....
The path must exist.
When concatenating a string with a path, the path must exist.
[source]
.Example
....
nix-repl> "/home/wombat" + ./no-such-file.txt
error (ignored): error: end of string reached
@ -93,6 +103,7 @@ For more information on these and other built-in functions, see the Nix Manual
Does the path exist?
[source]
.Example
....
nix-repl> builtins.pathExists ./index.html
true
@ -104,6 +115,7 @@ false
Get a list of the files in a directory, along with the type of each file.
[source]
.Example
....
nix-repl> builtins.readDir ./.
{ ".envrc" = "regular"; ".git" = "directory"; ".gitignore" = "regular"; Makefile = "regular"; images = "directory"; "index.html" = "regular"; "shell.nix" = "regular"; source = "directory"; themes = "directory"; "wombats-book-of-nix.pdf" = "regular"; }
@ -112,6 +124,7 @@ nix-repl> builtins.readDir ./.
Read the contents of a file into a string.
[source]
.Example
....
nix-repl> builtins.readFile ./.envrc
"use nix\n"

View file

@ -41,4 +41,16 @@ The following commands are available:
A command that is useful to beginners is `:t`, which tells you the type of an expression.
[source]
.Example
....
nix-repl> :t { abc = true; "123" = false; }
a set
nix-repl> f = x: y: x * y
nix-repl> :t f
a function
....
Note that the command to exit the REPL is `:q` (or `:quit` if you prefer).

View file

@ -1,10 +1,38 @@
= String operations
== String comparison
Nix provides the usual lexicographic comparison operations.
[source]
.Example
....
nix-repl> "apple" == "banana" # equality
false
nix-repl> "apple" != "banana" # inequality
true
nix-repl> "apple" < "banana" # comes alphabetically before?
true
nix-repl> "apple" <= "banana" # equal or comes alphabetically before?
true
nix-repl> "apple" > "banana" # comes alphabetically after?
false
nix-repl> "apple" >= "banana" # equal or comes alphabetically after?
false
....
== String concatenation
String concatenation uses the `+` operator.
[source]
.Example
....
nix-repl> "Hello, " + "world!"
"Hello, world!"
@ -15,6 +43,7 @@ nix-repl> "Hello, " + "world!"
You can use the `${_variable_}` syntax to insert the value of a variable within a string.
[source]
.Example
....
nix-repl> name = "Wombat"
@ -28,6 +57,7 @@ You cannot mix numbers and strings.
Earlier we set `a = 7`, so the following expression fails.
[source]
.Example
....
nix-repl> "My favourite number is ${a}."
error:
@ -40,7 +70,7 @@ error:
error: cannot coerce an integer to a string
....
Nix does provide functions for converting between types; we'll see these in the
Nix does provide functions for converting between types; we'll see these in the
<<#convert-to-string,next section>>.
====
@ -54,6 +84,7 @@ For more information on these and other built-in functions, see the Nix Manual
How long is this string?
[source]
.Example
....
nix-repl> builtins.stringLength "supercalifragilisticexpialidocious"
34
@ -63,6 +94,7 @@ Given a starting position and a length, extract a substring.
The first character of a string has index `0`.
[source]
.Example
....
nix-repl> builtins.substring 3 6 "hayneedlestack"
"needle"
@ -72,6 +104,7 @@ nix-repl> builtins.substring 3 6 "hayneedlestack"
Convert an expression to a string.
[source]
.Example
....
nix-repl> builtins.toString 7
"7"

View file

@ -94,11 +94,22 @@ attribute sets are simply called "sets".
[#type-lambda]
== Functions
We'll learn how to write functions later in this chapter.
We'll learn how to write functions in <<#functions>>.
For now, note that functions are "first-class values",
meaning that they can be treated like any other data type.
For example, a function can be assigned to a variable, appear as an element in a list,
or be associated with a key in an attribute set.
be associated with a key in an attribute set, or be passed as input to another function.
[ "apple" 123 ./build.sh false (x: x*x) ]
{ name = "Professor Paws"; age = 10; species = "cat"; formula = (x: x*2); }
[#type-derivation]
== Derivations
A https://nix.dev/manual/nix/latest/store/derivation/[derivation]
is an attribute set, but one which is a recipe for producing a Nix package.
We'll learn how to write derivations in <<#derivations>>.
For now, note that derivations are "first-class values",
meaning that they can be treated like any other data type.
For example, a derivation can be assigned to a variable, appear as an element in a list,
be associated with a key in an attribute set, or be passed as input to a function.

View file

@ -7,6 +7,7 @@
You can declare variables in Nix and assign values to them.
[source]
.Example
....
nix-repl> a = 7
@ -24,6 +25,7 @@ Nix allows hyphens (`-`) in variable names,
so `a-b` is interpreted as the name of a variable rather than a subtraction operation.
[source]
.Example
....
nix-repl> a-b
error: undefined variable 'a-b'
@ -52,6 +54,7 @@ effectively creating a new nested scope with each assignment.
This makes it much easier to experiment in the REPL.
[source]
.Example
....
nix-repl> x = 1

View file

@ -4,6 +4,7 @@ A `with` expression is somewhat similar to a `let` expression,
but it brings all of the associations in an attribute set into scope.
[source]
.Example
....
nix-repl> point = { x1 = 3; x2 = 2; }
@ -18,6 +19,7 @@ Unlike a `let` expression, a variable defined inside a `with` expression will _n
"shadow" an outer variable with the same name.
[source]
.Example
....
nix-repl> name = "Amy"
@ -31,6 +33,7 @@ However, you can refer to the variable in the inner scope
using the attribute selection operator (`.`).
[source]
.Example
....
nix-repl> with animal; "Hello, " + animal.name
"Hello, Professor Paws"

View file

@ -1,3 +1,4 @@
[#shebang]
= Scripts
You can use `nix shell` to run scripts in arbitrary languages, providing