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

3 Likes

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.

2 Likes

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 foo.3.bar 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.
6 Likes

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