raccoon's zone!

This web is still being woven. Please don't be surprised if it changes from time to time...

last updated 2024-01-29 for nix 2.13 - 2.18, nixos 23.05 - 23.11

The Nitpicks Page

Sometimes I skip over some little details to make things feel more conceptually elegant or whatever. Usually these details are too irrelevant to the issue at hand, or too out of scope of the proficiency level the document was intended for, that they don't even deserve an infobox aside.

However, I don't ever want to mislead, so this page is for making those kinds of details clear!

If you have any questions, complaints, or suggestions, contact us!

Reproducibility of Derivations

Nix certainly makes it easier to specify a build that produces the same output on any system of a given platform, but it isn't magic. For instance, you can have a working derivation that runs echo $RANDOM >$out to produce its output, with no complaint from Nix.

The extensional model (the one I describe, where output paths are derived from their inputs), is an obvious and elegant one for the reason that knowing output paths a priori is convenient for binary caching and for avoiding path rewriting after the fact. However, it makes no attempt to mitigate this problem: my random-number derivation will produce an object with the same path but different contents on every system.

Given well-behaved builds and trusted substituters, this caveat is not normally a problem. I'll leave more insidious, less obvious forms of build nondeterminism to your imagination. For fun, you can check how much nondeterminism still exists in NixOS isos at this page!

If you want to learn about the experimental mitigation for this problem, wherein output paths are rewritten to be content-addressed, and thus nondeterministic builds do receive nondeterministic output paths, see The purely functional software deployment model, chapter 6 or Nix RFC 0062, Content-addressed paths.

derivationStrict

Actually, derivation isn't the barest primitive for producing store derivations from inside Nix. It's just a wrapper function around the real primop, derivationStrict.

In essence, the wrapper just takes the output of derivationStrict (which only produces a set containing drvPath and attributes from output-name to output-path) and massages it into the more featureful output I describe in Writing Packages.

There is no reasonable circumstance where you would need to know this or call derivationStrict yourself (unless you happen to be making a Nix language implementation). It's just an interesting tidbit :)