Skip to content

Commit

Permalink
search path -> lookup path
Browse files Browse the repository at this point in the history
recent additions to the Nix manual clarify the distinction between
search path and lookup path, and also document the resolution algorithm.

lookup paths are now a distinct Nix language construct with its own
reference documentation.
  • Loading branch information
fricklerhandwerk committed Oct 7, 2023
1 parent 8ef0966 commit 446fe09
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
10 changes: 5 additions & 5 deletions source/recipes/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ buildInputs = builtins.attrValues {
:::

(search-path)=
## `<...>` search path
## `<...>` lookup paths

You will often encounter Nix language code samples that refer to `<nixpkgs>`.

Expand All @@ -119,8 +119,8 @@ You will often encounter Nix language code samples that refer to `<nixpkgs>`.
[introduced in 2011]: https://github.com/NixOS/nix/commit/1ecc97b6bdb27e56d832ca48cdafd3dbb5185a04
[`$NIX_PATH`]: https://nixos.org/manual/nix/unstable/command-ref/env-common.html?highlight=nix_path#env-NIX_PATH

This means, the value of a search path depends on external system state.
When using search paths, the same Nix expression can produce different results.
This means, the value of a lookup path depends on external system state.
When using lookup paths, the same Nix expression can produce different results.

In most cases, `$NIX_PATH` is set to the latest channel when Nix is installed, and is therefore likely to differ from machine to machine.

Expand All @@ -138,10 +138,10 @@ Builds may work for one and fail for the other, causing confusion.
:::{tip}
Declare dependencies explicitly using the techniques shown in [](ref-pinning-nixpkgs).

Do not use search paths, except in examples.
Do not use lookup paths, except in examples.
:::

Some tools expect the search path to be set. In that case:
Some tools expect the lookup path to be set. In that case:

::::{tip}
Set `$NIX_PATH` to a known value in a central location under version control.
Expand Down
22 changes: 11 additions & 11 deletions source/tutorials/first-steps/nix-language.md
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ Paths can be used in interpolated expressions – an [impure operation](impuriti
:::

(search-path-tutorial)=
#### Search path
#### Lookup paths

Also known as “angle bracket syntax”.

Expand All @@ -953,7 +953,7 @@ Example:
/nix/var/nix/profiles/per-user/root/channels/nixpkgs
```

The value of a named path is a file system path that depends on the contents of the [`$NIX_PATH`][NIX_PATH] environment variable.
The value of a [lookup path](https://nixos.org/manual/nix/unstable/language/lookup-path) is a file system path that depends on the value of [`builtins.nixPath`](https://nixos.org/manual/nix/stable/language/builtin-constants#builtins-nixPath).

In practice, `<nixpkgs>` points to the file system path of some revision of [`nixpkgs`][nixpkgs], the source repository of Nixpkgs.

Expand All @@ -969,7 +969,7 @@ For example, `<nixpkgs/lib>` points to the subdirectory `lib` of that file syste
/nix/var/nix/profiles/per-user/root/channels/nixpkgs/lib
```

While you will see many such examples, we recommend to [avoid search paths](search-path) in practice, as they are [impurities](impurities) which are not reproducible.
While you will see many such examples, we recommend to [avoid lookup paths](search-path) in practice, as they are [impurities](impurities) which are not reproducible.

[NIX_PATH]: https://nixos.org/manual/nix/unstable/command-ref/env-common.html?highlight=nix_path#env-NIX_PATH
[nixpkgs]: https://github.com/NixOS/nixpkgs
Expand Down Expand Up @@ -1628,28 +1628,28 @@ Example:
let
pkgs = import <nixpkgs> {};
in
pkgs.lib.strings.toUpper "search paths considered harmful"
pkgs.lib.strings.toUpper "lookup paths considered harmful"
```

```{code-block}
:class: value
SEARCH PATHS CONSIDERED HARMFUL
LOOKUP PATHS CONSIDERED HARMFUL
```

:::{dropdown} Detailed explanation

This is a more complex example, but by now you should be familiar with all its components.

The name `pkgs` is declared to be the expression `import`ed from some file.
That file's path is determined by the value of the search path `<nixpkgs>`, which in turn is determined by the `$NIX_PATH` environment variable at the time this expression is evaluated.
That file's path is determined by the value of the lookup path `<nixpkgs>`, which in turn is determined by the `$NIX_PATH` environment variable at the time this expression is evaluated.
As this expression happens to be a function, it requires an argument to evaluate, and in this case passing an empty attribute set `{}` is sufficient.

Now that `pkgs` is in scope of `let ... in ...`, its attributes can be accessed.
From the Nixpkgs manual one can determine that there exists a function under [`lib.strings.toUpper`].

[`lib.strings.toUpper`]: https://nixos.org/manual/nixpkgs/stable/#function-library-lib.strings.toUpper

For brevity, this example uses a search path to obtain *some version* of Nixpkgs.
For brevity, this example uses a lookup path to obtain *some version* of Nixpkgs.
The function `toUpper` is trivial enough that we can expect it not to produce different results for different versions of Nixpkgs.
Yet, more sophisticated software is likely to suffer from such problems.
A fully reproducible example would therefore look like this:
Expand Down Expand Up @@ -1755,7 +1755,7 @@ The only way to specify build inputs in the Nix language is explicitly with:
Nix and the Nix language refer to files by their content hash. If file contents are not known in advance, it's unavoidable to read files during expression evaluation.

:::{note}
Nix supports other types of impure expressions, such as [search paths](search-path) or the constant [`builtins.currentSystem`](https://nixos.org/manual/nix/stable/language/builtin-constants.html#builtins-currentSystem).
Nix supports other types of impure expressions, such as [lookup paths](search-path) or the constant [`builtins.currentSystem`](https://nixos.org/manual/nix/stable/language/builtin-constants.html#builtins-currentSystem).
We do not cover those here in more detail, as they do not matter for how the Nix language works in principle, and because they are discouraged for the very reason of breaking reproducibility.
:::

Expand Down Expand Up @@ -1900,12 +1900,12 @@ It may produce a different hash or even a different package version.

A derivation's output path is fully determined by its inputs, which in this case come from *some* version of Nixpkgs.

This is why we recommend to [avoid search paths](search-path) to ensure predictable outcomes, except in examples intended for illustration only.
This is why we recommend to [avoid lookup paths](search-path) to ensure predictable outcomes, except in examples intended for illustration only.
:::

:::{dropdown} Detailed explanation

The example imports the Nix expression from the search path `<nixpkgs>`, and applies the resulting function to an empty attribute set `{}`.
The example imports the Nix expression from the lookup path `<nixpkgs>`, and applies the resulting function to an empty attribute set `{}`.
Its output is assigned the name `pkgs`.

Converting the attribute `pkgs.nix` to a string with [string interpolation](string-interpolation) is allowed, as `pkgs.nix` is a derivation.
Expand Down Expand Up @@ -1952,7 +1952,7 @@ Explanation:

- This expression is a function that takes an attribute set as an argument.
- If the argument has the attribute `pkgs`, it will be used in the function body.
Otherwise, by default, import the Nix expression in the file found on the search path `<nixpkgs>` (which is a function in this case), call the function with an empty attribute set, and use the resulting value.
Otherwise, by default, import the Nix expression in the file found on the lookup path `<nixpkgs>` (which is a function in this case), call the function with an empty attribute set, and use the resulting value.
- The name `message` is bound to the string value `"hello world"`.
- The attribute `mkShell` of the `pkgs` set is a function that is passed an attribute set as argument.
Its return value is also the result of the outer function.
Expand Down

0 comments on commit 446fe09

Please sign in to comment.