How to Learn Nix, Part 0: How to Learn Nix


If someone particularly interested in the documentation / discovery / help problems has time for a project, mining Ian’s whole series of Nix posts for actionable bits would be a good one.

(Some actionable bits might be doc fixes/additions, some might be things that the community can help out with via blog posts / videos / etc.)

1 Like

The last post on getting nix-shell to work with any shell it’s invoked (zsh) is a big win I think.

I’d love to understand how to upstream that.


fwiw, you can do this without any real effort if you use direnv

1 Like

I’m using any-nix-shell and it’s working very well.

You revealed a bug in my OpenGraph titles :slight_smile:

mining Ian’s whole series of Nix posts for actionable bits would be a good one

I have actually done this mining myself, having read over all of my posts as a precursor to making documentation improvements. (Which I haven’t… actually done. Post forthcoming with weak excuses as to why).

But if anyone is hankering to improve the docs… just rewrite the quick start guide. I believe it’s the single biggest source of pain and confusion for self-taught Nix newcomers. As a close second, rewrite the example derivation so that it’s a default.nix instead of a Nixpkgs contribution, so that people can actually follow along with it.

Beyond those, here are my raw, unedited notes to myself. Lots of subjective opinions, so take these with a few grains of salt:

  • Glossary
    • Definition of “derivation” is not useful to someone who doesn’t already know what a derivation is.
    • Says that substitutes live in the Nix database, which they don’t.
    • The definition for “validity” is completely circular. Never explains how a derivation might be invalid.
    • “Store derivation” is a term used frequently – including in the glossary! – but never defined.
  • installation
    • For the macOS instructions, the diskX bit is confusing. But otherwise it’s pretty good, I thought.
  • quick start
    • Almost nothing in the quick start guide is correct.
  • 9
    • documentation around --file could be better
    • nix-env -qas is not good. Use nix-env -qasA.
    • This is the first time we see the term “set.”
  • 10
    • Diagram of profiles is immensely complicated and unnecessary.
    • It would have helped me if the manual explained that every file is symlinked (maybe mention something about fixupPhase canonicalizing the locations so that that makes sense?)
  • 11
    • It was weirdly hard for me to figure out where the nix config file is supposed to live? The man pages do not really explain this.
    • No explanation of keep-outputs or keep-derivations. Or rather, the explanation given actively lies about what they do? It is at least very misleading.
  • 12
    • .tar.bz2 is now .tar.xz.
  • 14
    • Written assuming nixpkgs, which is not good
    • I think the treatment of stdenv isn’t great
    • Should describe function call syntax; that’s not going to be familiar to a lot of people.
    • “Building something from other stuff is called a derivation in Nix”
    • “We perform a derivation”
    • “mkDerivation is a function provided by stdenv that builds a package from a set of attributes.”
    • Uses “set” instead of attribute set
    • Should call out that a path is not a string.
    • Mention that the $stdenv env var is set because stdenv.mkDerivation
    • Maybe some pointers to later discussions of stdenv?
    • I was very confused whether or not $stdenv was required.
    • Mention that fetchurl is a derivation
      • “The src attribute was bound to the result of fetching the Hello source tarball from the network, so the src environment variable points to the location in the Nix store to which the tarball was downloaded”
    • “The perl environment variable points to the location of the Perl package (since it was passed in as an attribute to the derivation)” could be more clear
    • Maybe mention that this script must create “$out” as a file or directory
  • 14.3
    • This is describing how to add a package to nixpkgs. It should describe how to write a simple default.nix file instead.
    • foo = import bar { inherit qux; }; maybe deserves a callout explaining how to parse that.
    • I was upset by the callPackage thing, but I don’t think there’s really anything to change there.
  • 14.4
    • “You can now try to build Hello” no… you can’t. The manual has not given a working example at this point.
    • This is where i got confused by the bin/ thing, but I think that should be explained earlier, not here.
    • “The -A option selects the hello attribute” is confusing to me.
  • 14.5
    • “Generic Builder Syntax” no it isn’t
    • I thought pkg/nix-support/setup-hook was stale, because I didn’t realize that it was talking about a path in the Nix store, not the Nixpkgs repo.
  • 15
    • “Its main job is to describe packages, compositions of packages, and the variability within packages.” I still have no idea what this statement is supposed to mean.
    • Maybe worth mentioning that because Nix is expression-oriented, every file has one value.
    • Should really mention nix repl right off the bat.
  • 15.1
    • I hate that “basic types” are separate from regular types. Show me all the types at once.
    • Derivations are not listed as a type, although they sort of are their own type, maybe, in some ways that I still don’t understand.
    • The string interpolation section is very confusing; just show concrete examples. Nix Pills has a better treatment.
    • Should mention paths can like… filter files. They are not isomorphic to strings.
    • Sets should use the term “attribute sets” at least once, to prevent frustration.
    • The __functor example is very confusing, using x twice in two different contexts.
  • 15.2
    • I would call out the difference between variables and bindings.
  • 15.4
    • “To figure out your platform identifier, look at the line ‘Checking for the canonical Nix system name’ in the output of Nix’s configure script.” Or just… builtins.currentSystem.
    • I had a really bad time by not setting out as an output name. There shouldn’t be an example in the manual that does that.
    • I had a lot of trouble with args; I don’t think that’s too important. Maybe a note that you shouldn’t use args; you should use environment variables instead.
    • “Each output path is a concatenation of the cryptographic hash of all build inputs, the name attribute and the output name” oxford comma
    • This section is about derivations but it never actually says what a derivation is. Nor does the section on types.
  • 15.5
    • Never explains throw vs abort. No idea what the difference is.
    • toString might want to mention drvPath in addition to __toString
    • Absolutely no idea what builtins.placeholder is for.
    • seq and deepSeq are not explained.
    • This list leaves out lots of other builtin functions.
  • 18
    • “This hook is only executed if the results are not the same, this hook is not used for determining if the results are the same.” should be a semicolon
  • 19
    • “using the” title is cut off
  • 20
    • There is documentation in this chapter about arrays, and an example of array indexing with syntax. This concept just… doesn’t seem to exist in Nix? What is this?
  • 22
    • --set-flag is sort of weird and confusing. But this barely matters.
    • The manual uses the term “package” when I think it means “derivation.” Unless it actually means like… derivations with a meta field? I don’t know. The term “package” is never defined or explained.
    • Manual states that nix-shell “Defaults to the bash found in PATH.” This is… technically true, pretty misleading. I would say that it defaults to nixpkgs.bashInteractive in your NIX_PATH, and falls back to your PATH's bash if that doesn’t exist.

Thanks for compiling this. It will be really helpful with GitHub - divnix/nix-book: The Nix Package Manager :slight_smile: