mirror of
https://codeberg.org/mhwombat/nix-book.git
synced 2026-05-12 19:43:57 +08:00
expanded
This commit is contained in:
parent
d0be400f85
commit
96f65dd5a5
11 changed files with 102 additions and 7 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
[#shebang]
|
||||
= Scripts
|
||||
|
||||
You can use `nix shell` to run scripts in arbitrary languages, providing
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue