Skip to content

OCF Nix Decal Lecture

Presented to you by the

and jaysa :)

What is Nix?

First, Nix is a functional programming language. Nix is:

  1. domain-specific: it is meant for creating nix derivations
  2. functional: functions can be passed as args and returned as values
  3. pure: the only result of a function is the value it returns; no side-effects.
  4. lazily evaluated: expressions are not evaluated until the value is needed
  5. dynamically typed: type-checking is done at runtime
  6. declarative: think SQL. you state what the output should be, the computer decides what steps to execute to get there.
  7. reproducible: same inputs to a nix program guarantees the same output

Tools heavily associated with nix are built using this language and reap those benefits. This includes NixOS and the Nix package manager, which we will cover more later on today.

Basic Syntax

from Zero to Nix and the nix.dev manual

I'll show my personal nix config for this laptop to illustrate.

Strings

"Can be written like this"

''
  Or, they can be written
  Like this
    This line will be indented by 2 spaces in the final output.
  But the rest won't be indented at all!
''

New lines in the second form will persist in the final output.

Lists

my_list = [ 123 ./foo.nix "abc" (f { x = y; }) ]

The final element of this list calls f on an attribute set? What is an attribute set, you ask...?

Attribute Sets

Collections of name-value pairs.

{
  x = 123;
  text = "Hello";
  y = f { bla = 456; };
}

{ a = "Foo"; b = "Bar"; }.a evaluates to Foo.

let bar = "foo"; in
{ foo = 123; }.${bar}

Both evaluate to 123.

Functions

{
  my_value = my_function 2 3;
}

Calls a function on parameters 2 and 3, assigns output to my_value.

{
  my_function = x: y: x + y;
}

Defines my_function.

NixOS

NixOS , like many other Linux distributions, is built around its package manager. But, machines running NixOS are configured using the Nix language. As a result, their configurations are fully reproducible.

Think about your current decal VM. If you wanted to replicate its state on another host exactly, how would you do it? Run all of the same commands and pray? What about if you hand-edited particular configuration files, such as /etc/fstab, when setting up the machine? Doing this imperatively is a big hassle that NixOS avoids

There are other tools, such as Terraform and Puppet, that try to solve this problem of declarative infrastructure, but do so a bit differently.

Resources (CRUCIAL FOR TODAY'S LAB)

What else?

Tips

  • To write good nix code, look at other people's good nix code!
    • The official NixOS github, for example. Or the ocf/nix repo (marginally less good).
    • check out contributors to Nix projects and see if their configurations or dotfiles are public
  • Be patient with Nix syntax. It'll give you a lot of errors at first, but you'll have less as you get better.
    • Additionally, take a look at nixfmt for code formatting.
  • Don't get too caught up in fully understanding Nix. You can still use it without knowing many of the theoretical nuances about what makes it so good just yet.