sets-and-decisions.md

Sets and decisions

Before this, you'll want

  1. Nix language basics
The Nix language12 min

Open any complex Nix file and the first thing you meet is a curly brace, and then, several hundred lines later, the one that closes it. Everything in between is one attribute set, and that is what this lesson is about.

They hold key-value pairs and look a lot like JSON objects, or objects in most other languages.

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Select a value with a dot

Each name on the left is an attribute name. We can use a dot to select the value paired with one of them:

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Sets can also nest. Give one key another set and you’ve got yourself a neat tree to work with. Then { a = { b = 2; }; }.a.b walks inward one name at a time.

Try it

Get the string "yes" out of this set.

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Name local values with let ... in

If there is one thing Nix hates, it is repetition. You’ll see more examples of that throughout the course, and let ... in is a tame one.

Since every Nix expression is technically just one value, Nix could never have used normal variables the way Python or JavaScript do. So let ... in acts more like a context shell around any other expression: names go after let, and the expression they serve goes after in. It can wrap numbers, lists or sets, giving them some immutable pieces to work with.

Think of defining variables, except they’re immutable, and the whole thing is still just an expression.

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Order does not matter here because Nix is lazy. A name only goes through evaluation when the final result needs it, so y may use x before x is written:

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Laziness also leaves an unused mistake asleep:

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

This is useful, but it is not error handling. Ask for broken and division by zero still breaks exactly as it should.

Compare values

A comparison produces a boolean. And == and != work on anything, not just numbers, comparing whole values as they go. Two lists are equal when every item in them is.

Try it

Make all three of these come out true.

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

Pick one of two values

if lets you choose between two expressions. Nix has no statements, so the condition and both outcomes are expressions. The entire block is one too.

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.
Try it

Say the password, so the guard answers "welcome".

nix replevaluated as you typeNixA plain Nix expression. Nothing from nixpkgs or a module system is supplied.

What to keep

  • Attribute sets pair names with values. Dots select values from them.
  • Nested dots walk through nested sets one name at a time.
  • let ... in creates local names and returns the expression after in.
  • Lazy evaluation wakes only the values the result needs.
  • Comparisons produce booleans.
  • if ... then ... else ... always has both outcomes because it is one expression.

Useful links

NORMALCOURSE IN BETA