Skip to content

Instantly share code, notes, and snippets.

@joepie91

joepie91/.md Secret

Created June 3, 2019 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joepie91/ca811a0c8d8e085da787be36072daf8d to your computer and use it in GitHub Desktop.
Save joepie91/ca811a0c8d8e085da787be36072daf8d to your computer and use it in GitHub Desktop.

In Nix / NixOS, how do I...?

Functions under builtins.* are part of the Nix language/runtime itself. They are always available under the exact identifier stated here (ie. including the builtins. prefix).

Operators are available exactly as specified, as a part of the Nix language/runtime. Things like e, e1, e2 are placeholders for the values or identifiers that you would apply the operator to. These placeholders are also used in some operator-like function descriptions.

Functions under lib.* are part of nixpkgs' set of utility functions. They are available as <nixpkgs>.lib.<functionname>, where nixpkgs is a reference to your nixpkgs package set, and functionname is the name of the function. So for example, lib.bitNot might be called like so, in a typical nixpkgs expression:

pkgs.lib.bitNot a b

To try things out in a REPL, run nix repl, and then run the following expression to make the nixpkgs utility methods available under lib:

lib = ((import <nixpkgs>) {}).lib

Then you can try out all of the examples below!


Control flow

  • FIXME: flip
  • FIXME: match expression?

Comparisons and boolean logic (including bitwise)

Operators

From strongest to weakest binding.

  • e1 < e2, e1 <= e2, e1 > e2, e1 >= e2: Is less than, is less than or equal, is more than, is more than or equals.
  • e1 == e2, e1 != e2: Is equal, is not equal.
  • e1 && e2: Logical AND (are both true?)
  • e1 || e2: Logical OR (is either of the two true?)
  • e1 -> e2: Logical implication (equivalent to !e1 || e2)

Utility functions

  • lib.bitAnd e1 e2: Bitwise AND
  • lib.bitOr e1 e2: Bitwise OR
  • lib.bitXor e1 e2: Bitwise XOR
  • lib.bitNot e1 e2: Bitwise NOT

The bitAnd, bitOr, and bitXor functions are re-exported versions of built-in functions of the same name, and are therefore also available under builtins.*.


Mathematical operations

A warning about division: Division in Nix is either integer or 'regular' division, depending on the operands. For example, if you divide two integers, you may get an unexpected result:

9 / 2 == 4

If you want to ensure that two integers are divided in a 'normal' way, with a fractional part like you might expect, you can multiply the first(!) operand by a floating-point number explicitly:

1.0 * 9 / 2 == 4.5

# or with identifiers:
1.0 * a / b

The same applies to the function version, builtins.div.

Operators

From strongest to weakest binding.

  • -e: Negate number (only without a space after the dash!)
  • e1 * e2, e1 / e2: Multiplication, division
  • e1 + e2, e1 - e2: Addition, subtraction

Most (FIXME: ?) operators are also available as functions:

  • builtins.mul e1 e2: Equivalent to e1 * e2.
  • builtins.div e1 e2: Equivalent to e1 / e2.
  • builtins.add e1 e2: Equivalent to e1 + e2.
  • builtins.sub e1 e2: Equivalent to e1 - e2.

Utility functions

  • lib.mod dividend divisor: The remainder of a division, eg. lib.mod 11 10 == 1.
  • lib.min e1 e2: Return the lowest of two numbers.
    • For a list of numbers: FIXME
  • lib.max e1 e2: Return the highest of two numbers.
    • For a list of numbers: FIXME

List (array) operations

  • FIXME: fold (also called reduce), left and right
  • FIXME: map
  • FIXME: filter

Attribute set (object) operations

FIXME


Type checks

  • FIXME: typeOf
  • FIXME: is*

Type conversions

Boolean to string

lib.boolToString value
  • value: The boolean value to convert.

The returned string will always be either "true" or "false". This is different from toString, which returns illogical results when you pass in a boolean.

Number to string:

builtins.toString value
  • value: The numeric value to convert.

JSON

Data to JSON (stringify)

builtins.toJSON value
  • value: The value to stringify. This can be of any type.

Type conversion rules:

  • Integers and floats are mapped to a number. How accurate numbers are is undefined in JSON, but you should expect them to be parsed by other software as floats.
  • Strings, booleans, and nulls are mapped to the same type in JSON.
  • Lists are mapped to arrays.
  • Attribute sets are mapped to objects, but...
  • Derivations are mapped to their output path. FIXME: Verify whether this also causes them to be evaluated, or not.
  • Paths are copied to the store, and mapped to their store path (as a string).

Data from JSON (parse)

builtins.fromJSON json
  • json: The JSON string to parse.

Type conversion rules:

  • Numbers are mapped to a float. FIXME: Is this even true for fraction-less numbers?
  • Strings, booleans and nulls are mapped to the same type in Nix.
  • Arrays are mapped to lists.
  • Objects are mapped to attribute sets.

Note that derivation and store path strings (originating from a builtins.toJSON call) are not parsed back into derivations and Nix paths, respectively. They will be parsed into a Nix string like any other string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment