Nix Tutorial 2 : Data Types & Language Constructs - wimsio/universities GitHub Wiki

This guide introduces the types of data in Nix and the main language features, with simple explanations, icons, and real examples for newcomers.


๐Ÿ“ Table of Contents

  1. Data Types Overview

  2. Primitive Types

  3. Compound Types

  4. String Context (Advanced)

  5. Nix Language Constructs

  6. String Interpolation

  7. Operators

  8. Summary Table

  9. Further Reading


Data Types Overview

Every value in Nix has a type. Knowing these types helps you write correct and maintainable Nix expressions.


Primitive Types ๐Ÿ”ข

1. Integer ๐Ÿงฎ

  • Description: Signed 64-bit numbers, e.g., 123, -42

  • Example:

    let
      a = 5;
      b = -3;
    in a + b  # Result: 2
  • Check type: builtins.isInt a โ†’ true


2. Float ๐ŸŒŠ

  • Description: 64-bit floating-point numbers, e.g., 1.5, -0.02, .1e5

  • Example:

    let pi = 3.1415;
    in pi * 2  # Result: 6.283
  • Check type: builtins.isFloat pi โ†’ true


3. Boolean ๐Ÿ”˜

  • Description: Only two values: true or false

  • Example:

    let flag = true;
    in if flag then "Yes" else "No"  # Result: "Yes"
  • Check type: builtins.isBool flag โ†’ true


4. String ๐Ÿ’ฌ

  • Description: Immutable sequence of bytes (not characters!); written with double quotes "foo" or indented strings ''foo''

  • Example:

    let msg = "Hello, Nix!";
    in msg
    let multi = ''
      Line 1
      Line 2
    '';
    in multi
  • Check type: builtins.isString msg โ†’ true


5. Path ๐Ÿ“

  • Description: POSIX-style file paths (e.g., ./file.txt, /etc/hosts). Paths and strings are not the same.

  • Example:

    let f = ./file.txt;  # relative path
        g = /etc/hosts;  # absolute path
    in f
  • Check type: builtins.isPath f โ†’ true

Note: Paths are resolved relative to their base directory. "./foo.txt" (as a string) is different from ./foo.txt (as a path).


6. Null ๐Ÿšซ

  • Description: The single value null (like "nothing" or "None" in other languages)

  • Example:

    let val = null;
    in if val == null then "empty" else "not empty"
  • Check type: val == null โ†’ true


Compound Types ๐Ÿ“š

1. Attribute Set ๐Ÿ”‘

  • Description: Key-value pairs, like dictionaries or objects in other languages.

  • Example:

    let
      person = { name = "Alice"; age = 30; };
    in person.name  # Result: "Alice"
  • Check type: builtins.isAttrs person โ†’ true

Access keys: set.key Nested sets: { a = { b = 2; }; } โ†’ access with .a.b


2. List ๐Ÿ“‹

  • Description: Ordered collections (arrays) of values, in square brackets.

  • Example:

    let
      xs = [ 1 2 3 ];
    in builtins.length xs  # Result: 3
  • Check type: builtins.isList xs โ†’ true

Access elements: builtins.elemAt xs 0 โ†’ 1


3. Function ๐Ÿ”ง

  • Description: Functions are first-class in Nix. You can pass them around, store them, and call them.

  • Example:

    let
      inc = x: x + 1;
    in inc 4  # Result: 5
    let
      add = { x, y }: x + y;
    in add { x = 2; y = 3; }  # Result: 5
  • Check type: builtins.isFunction inc โ†’ true


4. External ๐Ÿงฉ (Advanced)

  • Description: Opaque values created by plugins. Usually not used in everyday Nix code.
  • Example: Not commonly encountered for new users.

String Context ๐Ÿงต (Advanced)

  • String context is metadata that tracks where a string came from (for reproducibility).

  • You donโ€™t need to deal with string context directly.

  • Checking context:

    builtins.hasContext "hello"  # false
    builtins.getContext (builtins.storePath "/nix/store/xyz-foo")
  • Clearing context:

    builtins.unsafeDiscardStringContext someString
  • Most users never need to touch thisโ€”just know it exists!


Nix Language Constructs โš™๏ธ

1. Basic Literals

  • String: "hello", ''multi-line''
  • Number: 42, 1.2, -7
  • Path: ./foo.txt, /etc/passwd
  • List: [ 1 2 3 ]
  • Attribute set: { key = "val"; }

2. Attribute Sets

  • Define:

    { a = 1; b = "foo"; }
  • Access:

    { a = 1; } .a  # 1
  • Default value:

    { a = 1; } .b or 42  # 42
  • Complex keys:

    { "foo bar" = 123; }."foo bar"  # 123

3. Recursive Sets

  • Allow self-reference among keys:

    rec {
      x = y;
      y = 10;
    }.x  # Result: 10

4. Let-Expressions

  • Define local variables:

    let a = 1; b = 2; in a + b  # 3

5. Inheriting Attributes

  • Copy from scope or other set:

    let x = 5; in { inherit x; y = 3; }  # { x = 5; y = 3; }
    let set = { a = 1; b = 2; };
    in { inherit (set) a; }
    # { a = 1; }

6. Functions

  • Anonymous function:

    x: x * 2
  • Function with attribute set as argument:

    { a, b }: a + b
  • Default value for function argument:

    { x, y ? 5 }: x + y
    ( { x, y ? 2 }: x * y ) { x = 3; }  # 6

7. Conditionals

  • If-else:

    if true then "yes" else "no"

8. Assertions

  • Check conditions, fail early if not met:

    assert 1 < 2; "ok"  # "ok"
    assert false; "fail"  # Error!

9. With-Expressions

  • Bring all attributes into scope:

    let as = { x = 1; y = 2; };
    in with as; x + y  # 3

10. Comments

  • Single line: # Comment

  • Multi-line:

    /*
    Block comment
    */

11. String Literals

  • Normal: "Hello, Nix!"

  • Indented/multi-line:

    ''
      First line
      Second line
    ''

12. Identifiers & Names

  • Start with a letter or _.
  • Can contain letters, digits, _, ', -.
  • Some words are reserved (like let, if, else).

String Interpolation ๐Ÿ’ก

  • Insert variables or expressions into strings with ${...}

  • Example:

    let name = "world";
    in "Hello, ${name}!"  # "Hello, world!"
  • In attribute names:

    let key = "foo";
    in { ${key} = 123; }
    # { foo = 123; }

Operators โž•

Arithmetic: +, -, *, / Comparison: <, >, ==, !=, <=, >= Logical: &&, ||, !, -> (implication) Update sets: // String concat: + List concat: ++ Path concat: +

  • Example:

    ( { a = 1; } // { b = 2; } )  # { a = 1; b = 2; }
    [ 1 2 ] ++ [ 3 4 ]  # [ 1 2 3 4 ]

Summary Table ๐Ÿ“–

Type Example Check Type
Integer 123 builtins.isInt 123
Float 3.14 builtins.isFloat 3.14
Boolean true builtins.isBool true
String "foo" builtins.isString "foo"
Path ./file.txt builtins.isPath ./file.txt
Null null val == null
Attribute Set { a = 1; } builtins.isAttrs {}
List [ 1 2 3 ] builtins.isList [1]
Function x: x + 1 builtins.isFunction (x: x)
External Plugin-defined N/A

Further Reading ๐Ÿ”—


โš ๏ธ **GitHub.com Fallback** โš ๏ธ