Skip to content

Instantly share code, notes, and snippets.

@cldellow
Last active November 15, 2017 16:26
Show Gist options
  • Save cldellow/e4388a13908019af5bb4a1d65d3969b5 to your computer and use it in GitHub Desktop.
Save cldellow/e4388a13908019af5bb4a1d65d3969b5 to your computer and use it in GitHub Desktop.

Nix thesis

I read https://nixos.org/~eelco/pubs/phd-thesis.pdf, which outlines Nix, a “functional” package manager.

It motivates the need for new take on package management by analogy to memory management in programming languages.

It contrasts how software deployment works today (“Fuck it, I’m sure /usr/bin/local/python is a reference to a python 2.7.12 install with PIL available”) to how we used to write software (“Fuck it, I’m sure 0x7FEA6072 is the address of the array of files; so clearly, assuming a 32-bit address space, the seventh file is at 0x7FEA608A.”)

In both cases, as long as your assumption was correct, things go swimmingly. But it could be easier and rely less on hoping your assumptions are correct.

Summary

  • First thought: “Chroot on steroids”
  • Second thought: “buildenv, but way, way better”
  • Packages are immutable and referentially transparent
  • Deployed software gets a unique path based on hash of what it is and what it depends on
    • Old: /usr/bin/bash
    • New: /nix/store/li1r4j6526vy84f8qg1ydfryp55xxxh1-bash-4.4-p12/bin/bash
  • Packages are defined in a custom language which describes how to install the package by explicitly enumerating its dependencies, sources, and the steps to build the output
    • ...but because Gentoo is terrible, Nix supports “referential transparency” -- you can install via a binary cache
    • ...this makes distributed builds possible
    • ...and sharing build artifacts across dev and CI machines
  • Move from run-time late binding to compile-time early binding
    • ...the application may still use late binding (eg DLLs, classloaders), but you express up front what versions you’ll be using and Nix injects them in the CLASSPATH or PATH in the correct order to ensure a repeatable runtime experience
  • Has a solution to the problem of how do you know you’ve captured all the dependencies of a package?
    • Again, they draw an analogy to memory management, stealing some ideas from conservative garbage collectors
  • Supports atomic installation of packages
  • Supports side-by-side installation of packages (due to unique name)
  • Has general-purpose binary patching algorithm

Pros

  • Reproducible builds!
  • Distributed builds!
  • Sharing build artifacts across dev/CI!
  • General-purpose builds!
    • Ie one Nix to rule them all, devs wouldn’t necessarily have to know the specific invocation of lein, sbt, mvn or python to build/test each project
  • Fast, reliable rollbacks (because atomic + side-by-side installations)!
  • Fast deployment (because binary patching can ship a ~20KB patch to a jar file instead of shipping a 20MB jar file)!
    • actually, appears this feature has been removed from modern nix

Cons

  • Totally reinvents the software deployment landscape
  • To be as safe as possible, should use NixOS -- a fully nixified OS
  • Yet Another Build Tool Language
    • ...at a glance, nix’s DSL seems less shitty than SBT’s DSL, so it’s got that going for it
  • Retrofit cost may be high
  • Unclear how the dev workflow looks like for python, Scala, Clojure apps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment