nani.wtf/src/posts/2022-10-16-the-arrow-operat...

2.1 KiB

title keywords image series
The nix arrow operator nix, language, programming-language ./images/nix_banner.png Nix shorts

There is a specal operator in nix, written as ->. It is not a c dereference struct pointer operator, nor is it a haskell function type definition. It is a boolean operator, which represents the "implies arrow" from propositional logic. This is especially useful in nix, because of its usage in modules.

The myService module

Let's say you have made a module for myService with two options called myService.enable, and myService.address. myService needs an address in order to work properly. If myService is not enabled, the value of myService.address doesn't really matter. Set or null, the result will be the same either way. If myService is enabled however, it is crucial that we report an error if myService.address is not set. myService can not work without it.

In order to make sure that this never happens, we need to assert that this is not the case. This could be done by asserting that this boolean expression is true.

((!myService.enable) || myService.address != null)

or in plain english: "Either myService is not enabled, or the address has to not be null"

This is equivalent to this boolean expression:

myService.enable -> myService.address != null

or in plain english: "myService being enabled implies that the address is not null".

Asserting these kinds of inter-setting dependencies are common enough in nix modules to provide grounds for having -> as its own boolean operator.

Full example

# modules/myService.nix
{ lib, config }: let
  cfg = config.myService;
in {
  options = {
    enable = lib.mkEnableOption "myService";
    address = lib.mkOption {
      example = "127.0.0.1";
      description = "The address of myService";
      type = lib.types.string;
    };
  };
  config = {
    # ...

    assertions = [
      {
        assertion = cfg.enable -> cfg.address != null;
        message = "myService needs an address";
      }
    ];
  };
}