lookups-and-strings.md

Lookups and long strings

Before this, you'll want

  1. Set shorthand
The Nix language10 min

Four new small pieces of syntax, none of them hard, and every one of them the kind of thing that stops you dead the first time it turns up in somebody else’s file.

Starting with the one that saves you from a crash.

Read a missing attribute with or

Reading an attribute that isn’t there stops evaluation cold. Put or after the lookup and Nix quietly uses whatever follows instead.

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

This or belongs to attribute selection and nothing else. It is not a general boolean operator, however much it looks like one.

Delete the or "localhost" and watch the same lookup turn into an error.

Try it

Give this lookup a fallback of 22, so it stops failing.

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

Ask whether an attribute exists

Sometimes you don’t want the value at all. You just want to know whether the name is there.

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

? answers true or false without ever reading the value. Yes, it is the same character you used for function defaults. It is doing a completely different job in a completely different position, and Nix expects you to keep up.

Recognize with

with someSet; throws that set’s names into scope on their own for the rest of the expression.

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

You will meet with pkgs; sitting in front of package lists absolutely everywhere, and it does read nicely.

Nix users complain about it constantly, though, and they are right to. Once a name arrives through with, neither you nor your editor can tell where it came from. And it quietly loses to any name already in scope, which is the half nobody expects.

PickA `let` above already binds `git`. Then you write `with pkgs; [ git ]`. Which git does the list get?

That one costs a morning when it happens to you, because the line reads perfectly correctly and the value is simply somebody else’s.

So recognize it in code you’re reading. When you write new code, prefer tools.git or inherit, where every name’s origin is written down.

Hold text across several lines

A normal string gets painful the moment you need a config file or a shell fragment. '' opens a string that spans lines and drops the indentation shared by every line, so your text can sit neatly inside the Nix code and still come out flush.

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

Notice that the deeper line keeps its extra gap. Only the indentation it shares with the Nix code disappears.

Try it

Move the server to port 8080.

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

Two escapes to file away for later. Inside '', a plain $ is perfectly fine, but if you need to stop ${ from opening an interpolation you write ''${, and a literal '' is written '''. You will need these rarely, which is precisely why this paragraph exists.

What to keep

  • set.x or fallback reads an attribute that might not be there.
  • set ? x asks whether it exists without reading it.
  • with set; opens names into scope but hides where they came from.
  • Prefer explicit selections or inherit when writing new code.
  • '' strings span lines and shed the indentation shared with your Nix code.

Useful links

NORMALCOURSE IN BETA