wlambda 0.8.1

WLambda is an embeddable scripting language for Rust
Documentation
[
  [
    "1 - Variable Definition and Assignment",
    [
      "",
      "As this manual assumes you have some programming knowledge,",
      "we will just take a short look at the variable definition and assignment",
      "syntax:",
      "",
      "```wlambda",
      "!a = 10;            # variable definition & initialization",
      "",
      ".a = 20;            # assignment of a new value to a variable",
      "```",
      "",
      "WLambda also supports destructuring assignment of vectors:",
      "",
      "```wlambda",
      "!v = $[1,2,3];",
      "!(a, b, c) = v;     # destructuring definition of variables",
      ".(a, b, c) = v;     # destructuring assignment",
      "",
      "std:assert_eq a 1;",
      "std:assert_eq b 2;",
      "std:assert_eq c 3;",
      "```",
      "",
      "This also works with maps, where the key names are matched to",
      "the variable names:",
      "",
      "```wlambda",
      "!m = ${ a = 10, b = 20, c = 30 };",
      "!(a, b, c) = m;     # destructuring definition by map",
      ".(a, b, c) = m;     # destructuring assignment by map",
      "",
      "std:assert_eq a 10;",
      "std:assert_eq b 20;",
      "std:assert_eq c 30;",
      "```",
      "",
      "And also with pairs:",
      "",
      "```wlambda",
      "!p = $p(10, 20);",
      "!(a, b) = p;",
      ".(a, b) = p;",
      "",
      "std:assert_eq a 10;",
      "std:assert_eq b 20;",
      "```",
      ""
    ]
  ],
  [
    "1.1 - Destructuring to Variables",
    [
      "",
      "Like highlighted in the previous section you can define and assign to",
      "multiple variables at once. Following data types support destructuring:",
      "",
      "- Vectors:",
      "```wlambda",
      "!(a, b, c) = $[1, 2, 3];",
      "",
      "std:assert_eq a 1;",
      "std:assert_eq b 2;",
      "std:assert_eq c 3;",
      "```",
      "- Maps:",
      "```wlambda",
      "!(x, foo, lol) = ${foo = 33, lol = 42, x = 2};",
      "",
      "std:assert_eq x   2;",
      "std:assert_eq foo 33;",
      "std:assert_eq lol 42;",
      "```",
      "- Pairs:",
      "```wlambda",
      "!(x, y) = $p(\"ex\", \"uepsilon\");",
      "",
      "std:assert_eq x \"ex\";",
      "std:assert_eq y \"uepsilon\";",
      "```",
      "- Numerical Vectors:",
      "```wlambda",
      "!(x, y, z) = $i(3, 44, 4);",
      "",
      "std:assert_eq x 3;",
      "std:assert_eq y 44;",
      "std:assert_eq z 4;",
      "",
      "!(r, g, b, a) = $f(0.3, 1.0, 0.4, 1.0);",
      "",
      "std:assert_eq r 0.3;",
      "std:assert_eq g 1.0;",
      "std:assert_eq b 0.4;",
      "std:assert_eq a 1.0;",
      "```",
      ""
    ]
  ],
  [
    "1.2 - Global Variables",
    [
      "",
      "You can define global variables that are not bound to",
      "a lexical scope as follows:",
      "",
      "```wlambda",
      "{",
      "    !:global a = 13;",
      "}[];",
      "",
      "std:assert_eq a 13;",
      "```",
      "",
      "Global variables however do not live beyond file or module boundaries.",
      ""
    ]
  ],
  [
    "1.3 - Constants",
    [
      "",
      "WLambda supports constant _variables_. These are global variables you can't",
      "assign to. They are resolved and inserted at compile time and offer a slight",
      "performance advantage (roughly 3-4%) over (global or local) variables.",
      "",
      "```wlambda",
      "!:const X = 11;",
      "",
      "std:assert_eq X 11;",
      "",
      "# Destructuring works too, but only with compile time literal values",
      "# in the vectors / maps:",
      "!:const (ON, OFF) = $[$true, $false];",
      "!:const (RED, BLUE) = ${",
      "    BLUE = 0x0000FF,",
      "    RED  = 0xFF0000,",
      "};",
      "",
      "std:assert_eq ON  $true;",
      "std:assert_eq OFF $false;",
      "",
      "std:assert_eq RED 0xFF0000;",
      "std:assert_eq BLUE 0x0000FF;",
      "```",
      "",
      "However, be aware that these _constants_ are not really constant.  Due to",
      "performance reasons referential values like Lists or Maps are not copied",
      "(neither shallow, nor deep) if you access them through a constant.",
      "",
      "```wlambda",
      "!:const V = $[1,2,3];",
      "",
      "std:assert_eq (str V) (str $[1,2,3]);",
      "",
      "std:push V 43;  # Mutation of a 'constant'",
      "std:assert_eq V.3 43;",
      "```",
      "",
      "Constants also work across module borders:",
      "",
      "```wlambda",
      "!:const X = 10;",
      "",
      "# When imported the X will remain constant:",
      "!@export X = X;",
      "```",
      ""
    ]
  ],
  [
    "2 - Functions (part 1/2)",
    [
      "",
      "A function can be defined using the `{ ... }` syntax and the `\\ _statement_`",
      "syntax: To give functions a name, you need to assign them to a variable with",
      "the `!_name_ = _expr_` syntax.",
      ""
    ]
  ],
  [
    "2.1 - Closures",
    [
      "",
      "Functions take values from the outer scope by promoting the variable",
      "at runtime to a hidden reference to their previous value:",
      "",
      "```wlambda",
      "!a = 10;",
      "!b = 20;",
      "",
      "# function transforms a and b to hidden references",
      "!add_a_and_b = { a + b };",
      "",
      "std:assert_eq add_a_and_b[] 30;",
      "",
      "# The assignment assigns to the hidden reference, so the closure add_a_and_b",
      "# also receives the new value:",
      ".a = 33;",
      "",
      "std:assert_eq add_a_and_b[] 53;",
      "",
      "# a and b are dereferenced on local variable access.",
      "std:assert_eq a + b         53;",
      "```",
      ""
    ]
  ],
  [
    "2.1.1 - Object Oriented Programming with Closures",
    [
      "",
      "This section explains how to create objects and hide state using closures.",
      "Keep in mind, that there are also `$self` and `$data` available, which",
      "allow a different approach for referring to the object state/data than to",
      "capture the object as reference in a closure.",
      "",
      "Keep in mind, that care must be taken (references need to be captures weakly)",
      "with the references as shown below, because otherwise you will get reference",
      "cycles and memory leaks.",
      "",
      "```wlambda",
      "!new_Cat = {!(name) = @;",
      "    # Captures by closures upgrade the outer `self` variable to a _hidden_",
      "    # reference, which is then captured. As the closure is stored in",
      "    # `self`, this would create a ref cycle. This is why we needed",
      "    # to make a weak reference to self.",
      "",
      "    # Make an explicit hidden reference:",
      "    !self_ = $& ${",
      "        name = name,",
      "    };",
      "",
      "    # Create a weak reference form the hidden reference:",
      "    !self = $weak& $:self_;",
      "",
      "    self.meow     = { std:displayln self.name \" meows!\"; };",
      "    self.get_name = { self.name };",
      "",
      "    # To keep the object alive, we retrieve a strong reference",
      "    # from the hidden reference:",
      "    $:self",
      "};",
      "",
      "!my_cat = new_Cat \"Spot\";",
      "",
      "my_cat.meow[]; # Prints 'Spot meows!'",
      "",
      "std:assert_eq my_cat.get_name[] \"Spot\";",
      "```",
      "",
      "Alternatively you can just make the cat name private:",
      "",
      "```wlambda",
      "!new_Cat = {!(name) = @;",
      "    # This does not make cycles, because `name` does not contain",
      "    # the closures in the end.",
      "    !cat_name = name;",
      "",
      "    !meow     = { std:displayln cat_name \" meows!\"; };",
      "    !get_name = { $*cat_name };",
      "    !set_name = { .*cat_name = _; };",
      "",
      "    # Just holds the methods",
      "    ${",
      "        meow     = meow,",
      "        get_name = get_name,",
      "        set_name = set_name,",
      "    };",
      "};",
      "",
      "!my_cat = new_Cat \"Spot\";",
      "",
      "my_cat.meow[]; # Prints 'Spot meows!'",
      "",
      "std:assert_eq my_cat.get_name[] \"Spot\";",
      "",
      "my_cat.set_name \"Spotty\";",
      "",
      "std:assert_eq my_cat.get_name[] \"Spotty\";",
      "```",
      ""
    ]
  ],
  [
    "2.2 - Function calling",
    [
      "",
      "To call functions, you have at least 4 alternatives. First is the bare",
      "`_expr_ arg1 arg2 arg3 arg4` syntax. And the second is the fully delimited",
      "variant: `_expr_[arg1, arg2, arg3, ...]`. You can always delimit the first",
      "variant using the `( ... )` parenthesis around the whole call,",
      "i.e. `(_expr_ arg1 arg2 arg3 arg4)`.",
      "",
      "Third you can call a function with a vector as argument with `_expr_[[_expr_]]`,",
      "where the second expression should return a vector (if it doesn't it will use the",
      "value as first argument).",
      "",
      "The fourth alternative is the `&>` and `<&` (and the apply variants `&@>` and",
      "`<@&`) argument pipe operators which can be conveniently used in conjunction",
      "with the first variant to prevent some parenthesis. Also belonging into the",
      "category of function calling operators there is the collection addition operators",
      "`+>` and `<+` which are described in their own section.",
      "",
      "Here are examples:",
      "",
      "```wlambda",
      "# All the second variant:",
      "std:assert_eq[std:str:cat[1, 2, 3], \"123\"];",
      "",
      "# Can also be written as:",
      "std:assert_eq (std:str:cat 1 2 3) \"123\";",
      "",
      "# As the third variant:",
      "!some_args = $[1, 2, 3];",
      "std:assert_eq std:str:cat[[some_args]] \"123\";",
      "",
      "# The fourth variant:",
      "std:assert_eq str <& $[1, 2, 3]     \"$[1,2,3]\";",
      "std:assert_eq $[1, 2, 3] &> str     \"$[1,2,3]\";",
      "```",
      "",
      "The arguments passed to the function are accessible using the `_`, `_1`, `_2`, ..., `_9`",
      "variables. If you need to access more arguments the `@` variable holds a vector of all",
      "arguments.",
      "",
      "```wlambda",
      "!twoify = { _ * 2 };",
      "",
      "std:assert_eq twoify[2] 4;",
      "",
      "!twoify2 = \\_ * 2;",
      "",
      "std:assert_eq twoify2[2] 4;",
      "",
      "# You may also call them directly, notice the parenthesis ( ... ) syntax",
      "# for delimiting the inner function call:",
      "std:assert_eq ({ _ * 2 } 2) 4;",
      "```",
      "",
      "If you want to name arguments, you can use the destructuring assignment",
      "syntax:",
      "",
      "```wlamdba",
      "!add = {!(a, b) = @;",
      "    a + b",
      "};",
      "",
      "std:assert_eq add[1, 2] 3;",
      "```",
      ""
    ]
  ],
  [
    "2.3 - Function arity checks",
    [
      "",
      "Functions check the number of arguments passed to them. The compiler tries to",
      "infer the number of arguments the function requires by looking at the parameter",
      "variables `_` to `_9` and `@`. If the compiler gets it wrong, you can:",
      "",
      "* Define minimum and maximum number of arguments with: `{|min < max| ... }`",
      "* Define exact number of arguments with: `{|num_of_args| ... }`",
      "* Accept any number of arguments: `{|| ... }`",
      "",
      "For the shortened function syntax there is:",
      "",
      "* `\\|min < max| ...`",
      "* `\\|num_of_args| ...`",
      "* `\\|| ...`",
      "",
      "Here an example:",
      "",
      "```wlambda",
      "!dosomething = {|2 < 4| !(a, b, c, d) = @;",
      "    # Please note: We have to assign the",
      "    # parameters to named values here, because",
      "    # the arms of the conditional below have",
      "    # their own set of arguments.",
      "",
      "    (is_none c) { a + b } { a * b + c * d }",
      "};",
      "",
      "std:assert_eq dosomething[1, 2]         3;",
      "std:assert_eq dosomething[2, 2, 3, 4]  16;",
      "```",
      ""
    ]
  ],
  [
    "2.3.1 - std:to_no_arity _function_",
    [
      "",
      "This function disables all arity checks of a function. Use this with care",
      "and diligence.",
      "",
      "```wlambda",
      "!f = { _ }; # accepts exactly 1 param",
      "",
      "# f keeps its arity checks, but f2 will",
      "# call the same function, but without arity checks.",
      "!f2 = std:to_no_arity f;",
      "",
      "std:assert_eq (f2 1 2 3) 1;",
      "```",
      ""
    ]
  ],
  [
    "2.4 - Calling fields / Method calling",
    [
      "",
      "If you use the '.' for accessing fields in a map,",
      "the object the most recent field is accessed of is passed",
      "to the called function. The object the function/method",
      "was called upon can be accessed using the special value '$self'.",
      "",
      "```wlambda",
      "!some_map = ${",
      "    some_func = { $self.a_value },",
      "    a_value = 11,",
      "};",
      "",
      "std:assert_eq some_map.some_func[] 11;",
      "```",
      "",
      "This in combination with the special key `'_proto'` can be used to",
      "implement a basic form of object orientation with prototype inheritance.",
      "",
      "It can also be combined with the closure OOP approach or used for",
      "other purposes.",
      "",
      "You can also use a vector/list as object, in that case the `_proto`",
      "field that holds the class method map is the first element of the",
      "vector. The second element of the vector can be accessed using `$data`.",
      ""
    ]
  ],
  [
    "2.4.1 - The $self and $data special variables",
    [
      "",
      "If you call a method using the dot `.`, and the value on the left",
      "side is a map or vector, you will get the map or vector by `$self`.",
      "However, if you define a `_data` key on the map, or put something in",
      "the second element of the vector, you can refer to it using `$data`.",
      "",
      "You can use this to refer to the members and other functions of a structure:",
      "",
      "```wlambda",
      "!new_ab_struct = {",
      "    ${",
      "        _data = ${ a = 1, b = 2 },",
      "        inc_a = { $data.a += 1; },",
      "        inc_b = { $data.b += 1; },",
      "        a = { $data.a },",
      "        b = { $data.b },",
      "        inc_both = {",
      "            $self.inc_a[];",
      "            $self.inc_b[];",
      "        },",
      "    }",
      "};",
      "",
      "!ab = new_ab_struct[];",
      "",
      "ab.inc_a[];",
      "std:assert_eq ab.a[] 2;",
      "",
      "ab.inc_b[];",
      "std:assert_eq ab.b[] 3;",
      "",
      "ab.inc_both[];",
      "std:assert_eq ab.a[] 3;",
      "std:assert_eq ab.b[] 4;",
      "```",
      "",
      "The next seconds show how this can be used to do prototyped object",
      "oriented programming.",
      ""
    ]
  ],
  [
    "2.4.2 - Object Oriented Programming with Prototypes",
    [
      "",
      "Instead of using closures for OOP the preferred way is to use",
      "maps of functions as classes and form an inheritance hierarchy",
      "by using the `'_proto'` key of a map:",
      "",
      "```wlambda",
      "!class_a = ${",
      "    # $self is set by any key access using the '.' calling form:",
      "    new = { ${ _proto = $self } },",
      "    generate = { \"I am A\" },  # A method",
      "};",
      "",
      "!a_instance = class_a.new[];",
      "",
      "std:assert_eq a_instance.generate[] \"I am A\";",
      "```",
      "",
      "The special key `'_data'` can be used (and is encouraged to be used)",
      "as storage for data members of your objects. This is useful to separate",
      "method name space inside objects from the data member namespace.",
      "To quickly access the data members you can use the special value `$data`,",
      "which will evaluate to `$self._data` in case `$self` is a map, and",
      "to `$self.1` in case `$self` is a vector.",
      "",
      "Here is an example with a map and data:",
      "",
      "```wlambda",
      "!class_b = ${",
      "    new = {",
      "        ${",
      "            _proto = $self, # $self is class_b",
      "            _data = ${",
      "                a = 10",
      "            },",
      "        }",
      "    },",
      "    gen  = { _ * $data.a },     # $data is equivalent to `$self._data` here",
      "    gen2 = { _ * $self._data.a },",
      "};",
      "",
      "!inst = class_b.new[];",
      "",
      "std:assert_eq inst.gen[2] 20;",
      "std:assert_eq inst.gen2[2] 20;",
      "```",
      "",
      "You can also use vectors as objects, which can be beneficial as they are",
      "a bit slimmer and access to `_proto` and `_data` are reduced to a single",
      "vector index lookup instead of an array lookup.",
      "",
      "```wlambda",
      "!class_b = ${",
      "    new = {",
      "        $[  # return a vector",
      "            $self, # $self is class_b",
      "            ${ a = 10 },",
      "        ]",
      "    },",
      "    gen  = { _ * $data.a },     # $data is equivalent to `$self.1` here",
      "    gen2 = { _ * $self.1.a },",
      "};",
      "",
      "!inst = class_b.new[];",
      "",
      "std:assert_eq inst.gen[3] 30;",
      "std:assert_eq inst.gen2[4] 40;",
      "```",
      ""
    ]
  ],
  [
    "2.4.3 - Object Oriented with Prototypes and Inheritance",
    [
      "",
      "You can inherit functionality from a different class by assigning",
      "it to the prototype of the class itself.",
      "",
      "```wlambda",
      "!SuperClass = ${",
      "    init_super_class = {",
      "        $data.inc = 0;",
      "    },",
      "    inc = {",
      "        $data.inc += 1;",
      "        $data.inc",
      "    },",
      "};",
      "```",
      "",
      "Please notice, that _SuperClass_ does not have it's own constructor,",
      "instead you should define a custom init function like `init_super_class`,",
      "to define the used fields. The _SuperClass_ will refer to the",
      "`$data` of the object that is going to be created by _MyClass_ in the next",
      "step.",
      "",
      "```wlambda",
      "!SuperClass = ${",
      "    init_super_class = {",
      "        $data.inc = 0;",
      "    },",
      "    inc = {",
      "        $data.inc += 1;",
      "        $data.inc",
      "    },",
      "};",
      "",
      "!MyClass = ${",
      "    _proto = SuperClass,",
      "    new = {",
      "        !self = ${",
      "            _proto = $self,",
      "            _data = ${ other = 10 },",
      "        };",
      "        self.init_super_class[];",
      "        self",
      "    },",
      "    get_other = { $data.other },",
      "    get_inc = { $data.inc },",
      "};",
      "",
      "!my_obj = MyClass.new[];",
      "",
      "std:assert_eq my_obj.get_other[] 10;",
      "std:assert_eq my_obj.inc[] 1;",
      "std:assert_eq my_obj.inc[] 2;",
      "std:assert_eq my_obj.inc[] 3;",
      "",
      "std:assert_eq my_obj._data.other 10;",
      "std:assert_eq my_obj._data.inc   3;",
      "```",
      ""
    ]
  ],
  [
    "2.4.4 - Object Oriented with Prototypes and $self References and $data References",
    [
      "",
      "There might come a time, when you want to pass a reference of your",
      "object around, but you want to prevent cyclic references.",
      "For this you will need to return a strong reference `$&&` from your",
      "constructor as `$self` and if you want to refer to `$data` from callback",
      "functions, you are advised to also wrap it into a strong reference.",
      "",
      "```wlambda",
      "!destroyed = $false;",
      "",
      "!MyClass = ${",
      "    new = {",
      "        $&& ${",
      "            _proto = $self,",
      "            _data  = $&& ${",
      "                x = 1",
      "            },",
      "            dropper = std:to_drop { .destroyed = $t; },",
      "        }",
      "    },",
      "    inc_x = { $data.x += 1 },",
      "    install_on = {!(callchain) = @;",
      "        !self = $w& $self;",
      "        std:push callchain { self.inc_x[]; };",
      "    },",
      "    install_getter = {!(callchain) = @;",
      "        !data = $w& $data;",
      "        std:push callchain { data.x };",
      "    },",
      "};",
      "",
      "# Create instance:",
      "!my_obj = MyClass.new[];",
      "",
      "my_obj.inc_x[];",
      "",
      "!chain = $[];",
      "my_obj.install_on     chain;",
      "my_obj.install_getter chain;",
      "",
      "# There are now 3 references to 'my_obj':",
      "# - my_obj variable",
      "# - first callback in chain",
      "# - second callback in chain",
      "",
      "std:assert_eq my_obj._data.x 2;",
      "chain.0[]; # calls my_ocj.inc_x[];",
      "std:assert_eq my_obj._data.x 3;",
      "",
      "# Second callback gets x:",
      "std:assert_eq chain.1[] 3;",
      "",
      "!my_obj = $n; # destroy only strong reference",
      "std:assert destroyed;",
      "```",
      "",
      "Of course the callbacks now refer to `$none` to call `inc_x`, a more",
      "sophisticated way of cleanup is of course necessary. But this is just an",
      "example.",
      ""
    ]
  ],
  [
    "2.5 - Function call composition",
    [
      "",
      "- chaining",
      "- traditional () call syntax",
      "- ~ syntax",
      "- || syntax",
      "",
      ">> $[] || push 10",
      "> $[10]",
      ">> $[] || push 10 || push 20",
      "> $[10,20]",
      ">> !x = { push _1 _ };",
      "> $n",
      ">> $[] | x 10 | x 20",
      "> $[10,20]",
      ">>",
      "",
      "- [...] syntax",
      ""
    ]
  ],
  [
    "2.5.1 - '|' Tail Argument Function Chaninig",
    [
      "",
      "This syntax is useful if you have following function call composition:",
      "",
      "```text",
      "(fn arg1 arg2 (fn2 arg_b1 arg_b2 (fn3 arg_c1 arg_c2 ...)))",
      "```",
      "",
      "These can be written more comfortably like this:",
      "",
      "```text",
      "fn3 arg1 arg2 | fn2 arg_b1 arg_b2 | fn arg1 arg2",
      "```",
      "",
      "An example with actual values:",
      "",
      "```wlambda",
      "!x = 10 | { _ * 4 } | { _ + 2 };",
      "",
      "std:assert_eq x 42;",
      "```",
      "",
      "Think of it as if the value `10` was _piped_ through the",
      "functions on the right.",
      "",
      "The call reordering of the `|` operator looks like this:",
      "",
      "```text",
      "    fn1 a1 a2 | fn2 b1 b2 (   )   =>   fn2 b1 b2 (fn1 a1 a2)",
      "    \"\"\"\"\"\"\"\"\"               ^",
      "        v                   |",
      "        --------------------|",
      "```",
      ""
    ]
  ],
  [
    "2.5.2 - '|>' Left Hand Function Chaining",
    [
      "",
      "This syntax is useful if you want to make deep call chains like these:",
      "",
      "```text",
      "(((fn arg1 arg2 ...) arg_b1 arg_b2 ...) arg_c1 arg_c2 ...)",
      "```",
      "",
      "These can be written more comfortably like this:",
      "",
      "```text",
      "fn arg1 arg2 |> arg_b1 arg_b2 |> arg_c1 arg_c2",
      "```",
      "",
      "or nicer formatted:",
      "",
      "```text",
      "fn arg1 arg2",
      "    |> arg_b1 arg_b2",
      "    |> arg_c1 arg_c2",
      "```",
      "",
      "Here an actual example:",
      "",
      "```wlambda",
      "!res = $@v",
      "    1 + 1",
      "    |> $[\"abc\", \"def\", \"ceg\"]",
      "    |> { $+ ~ std:str:cat \"|\" _ \"|\" };",
      "",
      "std:assert_eq res.0 \"|c|\";",
      "std:assert_eq res.1 \"|e|\";",
      "std:assert_eq res.2 \"|g|\";",
      "```",
      "",
      "The call reordering of the `|>` operator looks like this:",
      "",
      "```text",
      "    fn1 a1 a2 |> b1 b2    =>   ((   )   )",
      "    \"\"\"\"\"\"\"\"\"    \"\"\"\"\"            ^   ^",
      "        v          v              |   |",
      "        -----------|--------------|   |",
      "                   -------------------|",
      "```",
      ""
    ]
  ],
  [
    "2.5.3 - Forward Argument Pipe `arg &> fun`",
    [
      "",
      "This operator has the highest precedence over all other operators",
      "and is used to be able to write this:",
      "",
      "```wlambda",
      "if \"foob\" &> $r/f(^*)b/ {",
      "    std:assert_eq $\\.1 \"oo\";",
      "} {",
      "    std:assert $false;",
      "}",
      "```",
      "",
      "That means `f a &> b` is equivalent to writing `f[b[a]]` or `(f (b a))`.",
      "Chaining multiple is also possible and left associative: `a &> b &> c` is `(c (b a))`.",
      "You can see it as piping operation:",
      "",
      "```wlambda",
      "!r = \"ABC\" &> std:str:to_lowercase &> \\std:str:pad_start 10 \"0\" _;",
      "",
      "std:assert_eq r \"0000000abc\";",
      "```",
      ""
    ]
  ],
  [
    "2.5.4 - Forward Argument Apply Pipe `list &@> fun`",
    [
      "",
      "This operator is like `&>`. But it will call the function with the elements",
      "in the given _list_ as arguments.",
      "",
      "That means: `list &@> fun` is equivalent to `fun[[list]]`.",
      "",
      "```wlambda",
      "std:assert_eq $[2, 5] &@> `+`   7;",
      "```",
      ""
    ]
  ],
  [
    "2.5.5 - Reverse Argument Pipe `fun <& arg`",
    [
      "",
      "Like the `&>` operator this operator, but it has a lower precedence (does not bind",
      "as strongly as `&>`) and is right associative. That means you can write this:",
      "",
      "```wlambda",
      "!r = (\\std:str:pad_start 10 \"0\" _) <& std:str:to_lowercase <& \"ABC\";",
      "",
      "std:assert_eq r \"0000000abc\";",
      "```",
      "",
      "That means, writing `f <& a <& x` becomes `f[a[x]]` or `(f (a x))`.",
      ""
    ]
  ],
  [
    "2.5.6 - Reverse Argument Apply Pipe `list &@> fun`",
    [
      "",
      "This operator is like `<&`. But it will call the function with the elements",
      "in the given _list_ as arguments.",
      "",
      "That means: `fun <@& list` is equivalent to `fun[[list]]`.",
      "",
      "```wlambda",
      "std:assert_eq `+` <@& $[2, 5]   7;",
      "```",
      ""
    ]
  ],
  [
    "2.6 - Control Flow - Returning",
    [
      "",
      "WLambda uses labelled blocks for control flow, as returning from the current function would not be",
      "very helpful for the control flow in wlambda in case of conditional execution using the",
      "boolean calling semantics.",
      "",
      "```wlambda",
      "!some_func = \\:outer {",
      "    !x = 10;",
      "",
      "    # does stuff...",
      "",
      "    (x == 10) {",
      "        return :outer 20",
      "    };",
      "",
      "    # more stuff that is not executed if x == 10.",
      "}",
      "```",
      ""
    ]
  ],
  [
    "2.6.1 - return [_label_] _value_",
    [
      "",
      "Returns _value_ from the current function if no _label_ is given.",
      "If _label_ is given, the call stack will unwind until either a `block`",
      "or a function with the given _label_ is encountered.",
      "",
      "```wlambda",
      "!f = {",
      "    10;",
      "    return 20;",
      "    30",
      "};",
      "",
      "std:assert_eq f[] 20;",
      "```",
      "",
      "Here an example for unwinding two call frames:",
      "",
      "```wlambda",
      "!f = \\:x {",
      "    10;",
      "    { return :x 20 }[];",
      "    30;",
      "};",
      "",
      "std:assert_eq f[] 20;",
      "```",
      "",
      "The labels do not adhere to lexical scoping and are dynamically scoped:",
      "",
      "```wlambda",
      "!g = { return :x 30 };",
      "",
      "!f = \\:x { 20; g[]; 40 };",
      "",
      "std:assert_eq f[] 30;",
      "```",
      ""
    ]
  ],
  [
    "2.6.2 - block [label] _function_",
    [
      "",
      "Calls the _function_ with the given _label_ for `return`to jump to.",
      "",
      "If you just want to setup a point inside a function to jump to",
      "with `return` the `block` function is more convenient to use:",
      "",
      "```wlambda",
      "!y = 1;",
      "",
      "!res = block :x {",
      "    .y = y + 1;",
      "    (y >= 2) \\return :x 20;",
      "    .y = y + 1;",
      "    .y = y + 1;",
      "};",
      "",
      "std:assert_eq res 20;",
      "```",
      "",
      "The alternative is the less clear syntax would be in this case:",
      "",
      "```wlambda",
      "!y = 1;",
      "",
      "!res = \\:x {",
      "    .y = y + 1;",
      "    (y >= 2) \\return :x 20;",
      "    .y = y + 1;",
      "    .y = y + 1;",
      "}[];",
      "",
      "std:assert_eq res 20;",
      "```",
      ""
    ]
  ],
  [
    "2.6.3 - std:to_drop _function_ (or RAII, Destructors or Drop Functions)",
    [
      "",
      "You can create a function that is called when it is",
      "dropped/its reference count goes to 0.",
      "",
      "```wlambda",
      "!dropped = $false;",
      "",
      "!x = std:to_drop { .dropped = $true; };",
      "",
      "std:assert not[dropped];",
      "",
      ".x = $none;",
      "",
      "std:assert dropped;",
      "```",
      "",
      "Please note, that the drop function will be executed in a newly constructed",
      "default EvalContext, this means there is some overhead and that the EvalContext",
      "dependent results of `std:eval` might be different.",
      ""
    ]
  ],
  [
    "2.6.4 - std:time:now [_unit_]",
    [
      "",
      "Returns the current system time since the UNIX epoch (1970-01-01 00:00:00 UTC).",
      "If no _unit_ is specified, the default is `:ms`. Following units are available:",
      "",
      "- seconds: `\"s\"`",
      "- milliseconds: `\"ms\"`",
      "- microseconds: `\"us\"`",
      "- nanoseconds: `\"ns\"`",
      "",
      "```wlambda",
      "std:assert (std:time:now :s)  > 1000;",
      "std:assert (std:time:now :ms) > 1000;",
      "std:assert len[str[std:time:now :ns]] > 18;",
      "```",
      ""
    ]
  ],
  [
    "2.6.5 - std:srand [_seed_]",
    [
      "",
      "With this function you can seed the internal pseudo random number",
      "generator based on an unspecified PRNG algorithm, that might or might not",
      "change in the next WLambda version.",
      "If no _seed_ is provided, the current system time (in `ns` resolution) is used.",
      "If _seed_ is provided, it is set to the integer value of that.",
      "",
      "```wlambda",
      "std:srand[];",
      "",
      "std:srand 1000;",
      "```",
      ""
    ]
  ],
  [
    "2.6.6 - std:rand [_max-or-mode_]",
    [
      "",
      "Returns a random number between 0 and _max_.  The interval 0",
      "to _max-or-mode_ is closed/open, that means 0 is included but _max-or-mode_",
      "is not included.",
      "",
      "If _max-or-mode_ is a string `\"i64\"` or symbol `:i64`, then std:rand will",
      "return a random signed 64 bit integer.",
      "",
      "If _max-or-mode_ is not provided, a float number between 0.0",
      "and 1.0 (including 0.0 but not including 1.0) is returned.",
      "",
      "```wlambda",
      "std:srand 1234567890;",
      "",
      "!zeros = $@i iter i 0 => 1000 {",
      "    if std:rand[100] == 0 \\$+ 1;",
      "};",
      "",
      "!count_100 = $@i iter i 0 => 1000 {",
      "    if std:rand[100] == 100 \\$+ 1;",
      "};",
      "",
      "std:assert zeros     >  0;",
      "std:assert count_100 == 0;",
      "",
      "std:assert std:rand[] < 1.0;",
      "std:assert std:rand[] >= 0.0;",
      "```",
      "",
      "Please note: The PRNG algorithm used for `std:rand` may change",
      "without further notice. If you require your project to have consistent",
      "PRNG results across all WLambda versions use `std:rand:split_mix64_*`.",
      ""
    ]
  ],
  [
    "2.7 - Function utilities",
    [
      ""
    ]
  ],
  [
    "2.7.1 - is_fun _value_",
    [
      "",
      "Returns `$true` if _value_ is a function.",
      "",
      "```wlambda",
      "std:assert ~ is_fun {};",
      "std:assert ~ is_fun is_fun;",
      "std:assert ~ not ~ is_fun ${a=10};",
      "```",
      ""
    ]
  ],
  [
    "3 - Data Types",
    [
      ""
    ]
  ],
  [
    "3.1 - None sentinel value: `$n` or `$none`",
    [
      "",
      "This is a special sentinel value that is returned by functions and",
      "when a non existing field of a datastructure is accessed. It's semantic",
      "meaning is that there is no value.",
      "",
      "Most functions that expect a string value will turn a `$none` into an",
      "empty string. If you need an unambigous representation use `std:ser:wlambda`",
      "for dumping WLambda data structures.",
      "",
      "Please note for API design: In case of errornous states you should not",
      "return a `$none` but an `$error` value.",
      "",
      "```wlambda",
      "std:assert ~ $n                  == $none;",
      "std:assert ~ int[$n]             == 0;",
      "std:assert ~ float[$n]           == 0.0;",
      "std:assert ~ str[$n]             == \"\";",
      "std:assert ~ std:ser:wlambda[$n] == \"$n\";",
      "std:assert ~ is_none[$n];",
      "```",
      ""
    ]
  ],
  [
    "3.1.1 - is_none _value_",
    [
      "",
      "Returns `$true` if _value_ is `$none` or `$o()`.",
      "",
      "```wlambda",
      "std:assert ~ is_none $none;",
      "std:assert ~ is_none $o();",
      "std:assert ~ not ~ is_none $false;",
      "std:assert ~ not ~ is_none $o(10);",
      "```",
      ""
    ]
  ],
  [
    "3.1.2 - is_some _value_",
    [
      "",
      "Returns `$true` if _value_ is anything except `$none` or `$o()`.",
      "",
      "```wlambda",
      "std:assert ~ not ~ is_some $none;",
      "std:assert ~ not ~ is_some $o();",
      "std:assert ~ is_some $false;",
      "std:assert ~ is_some 30;",
      "std:assert ~ is_some $o(30);",
      "```",
      ""
    ]
  ],
  [
    "3.2 - Optional values `$o()` and `$o(...)`",
    [
      "",
      "An optional value can either contain another value, or contain no value at all.",
      "An empty optional value is not much different from `$none`, but it is sometimes",
      "desirabel to make a difference between an optional value and a `$none` value",
      "if the `$none` value is used as sentinel value.",
      "",
      "Optional values were introduced for functions that lookup stuff and either",
      "return _something_ that might be `$none` (eg. if some element in a vector is",
      "searched for), or return that nothing was found.",
      "",
      "The functions `is_none` and `is_some` like stated above work for these",
      "optional values too:",
      "",
      "```wlambda",
      "std:assert ~ is_none $o();",
      "std:assert ~ is_some $o(10);",
      "std:assert ~ is_some $o($none);",
      "std:assert ~ is_some $o($o());",
      "```",
      "",
      "Calling an optional value will return it's contents or `$none`:",
      "",
      "```wlambda",
      "std:assert_eq $o()[]     $none;",
      "std:assert_eq $o(10)[]   10;",
      "",
      "!do_something = {",
      "    if _ == 0 {",
      "        $o()",
      "    } {",
      "        $o(_ + 10)",
      "    }",
      "};",
      "",
      "!result = do_something 11;",
      "std:assert_eq result[] 21;",
      "",
      "!result = do_something 0;",
      "std:assert_eq result[] $none;",
      "```",
      "",
      "In a boolean context an optional becomes `$true` if it contains",
      "something and `$false` if it has nothing.",
      "",
      "```wlambda",
      "std:assert ~ not ~ bool $o();",
      "std:assert ~ bool $o(10);",
      "",
      "!x = $o();",
      "!res1 = if x \"something\" \"nothing\";",
      "std:assert_eq res1 \"nothing\";",
      "",
      ".x = $o(30);",
      "!res2 = if x \"something\" \"nothing\";",
      "std:assert_eq res2 \"something\";",
      "```",
      "",
      "Many other operations are just forwarded to the contents of the",
      "optional value:",
      "",
      "```wlambda",
      "std:assert_eq $o(33) + 44    77;",
      "",
      "!x = $o($[1,2,3]);",
      "std:push x 4;",
      "std:assert_eq (str x) (str $[1,2,3,4]);",
      "",
      "std:assert_eq (float $o(4.4))   4.4;",
      "std:assert_eq (int $o(4.4))     4;",
      "```",
      "",
      "An optional value can also be dereferenced:",
      "",
      "```wlambda",
      "std:assert_eq $*$o()    $none;",
      "std:assert_eq $*$o(10)  10;",
      "```",
      "",
      "Calls with more than zero arguments are forwarded to the contents:",
      "",
      "```wlambda",
      "std:assert_eq ($o(\"xx\") \"yy\")  \"xxyy\";",
      "",
      "!x = { _ * 20 };",
      "std:assert_eq ($o(x) 30)    600;",
      "```",
      ""
    ]
  ],
  [
    "3.2.1 - is_optional _value_",
    [
      "",
      "Returns `$true` if _value_ is an optional value. That means either `$o()` or",
      "`$o(...)`.",
      "",
      "```wlambda",
      "std:assert ~ is_optional $o();",
      "std:assert ~ is_optional $o($none);",
      "std:assert ~ is_optional $o(10);",
      "",
      "std:assert ~ not ~ is_optional $true;",
      "std:assert ~ not ~ is_optional $none;",
      "std:assert ~ not ~ is_optional $false;",
      "std:assert ~ not ~ is_optional 303;",
      "```",
      ""
    ]
  ],
  [
    "3.2.2 - Unwrapping optionals",
    [
      "",
      "You can unwrap an optional with `unwrap`. It will panic if there is no value provided.",
      "Otherwise it will return the contents.",
      "",
      "```wlambda",
      "std:assert_eq unwrap[$o(10)] 10;",
      "```",
      ""
    ]
  ],
  [
    "3.3 - Error values: `$e expr` or `$error expr`",
    [
      "",
      "There are no exceptions in WLambda, except the panic, that",
      "halts all execution of the currently running WLambda",
      "program. To signal errors, you return an `$error` value.",
      "",
      "These error values, if not handled, will cause a panic of your",
      "program. This means, you need to handle returned error values",
      "one way or the other.",
      "",
      "The error value wraps any value you pass to the `$error` or `$e`",
      "constructor syntax.",
      "",
      "```wlambda",
      "std:assert ~ is_err ~ $e \"something went wrong!\"",
      "```",
      "",
      "There are more routines except `is_err` to handle an error.",
      "`_?` will return from the currently executed function",
      "up until some given label. `on_error` executes a function",
      "if the second argument was an error value. Otherwise it",
      "just passes through the value. `unwrap` will explicitly cause",
      "an panic if an error value was passed to it. All other values",
      "will be passed through. And `unwrap_err` unwraps an error value, it's",
      "the opposite of `unwrap` because it will cause a panic if you don't pass",
      "an error value.",
      "",
      "Most functions don't accept errors in their arguments.",
      "If an error is encountered, a panic will occur. There are only",
      "a few functions that accept error values in their arguments:",
      "",
      "- panic",
      "- `_?`",
      "- unwrap_err",
      "- std:error_to_str",
      "- unwrap",
      "- on_error",
      "- return",
      "- break",
      "- bool",
      "- type",
      "- match",
      "- assert",
      "- assert_eq",
      "- is_some",
      "- is_none",
      "- is_err",
      "- is_map",
      "- is_vec",
      "- is_fun",
      "- is_str",
      "- is_wref",
      "- is_ref",
      "- is_bool",
      "- is_bytes",
      "- is_sym",
      "- is_float",
      "- is_optional",
      "- is_int",
      "- ==",
      "- !=",
      "- std:to_ref",
      "- std:ref_id",
      "- std:ser:wlambda",
      "",
      "All other functions don't accept errors as their argument.",
      ""
    ]
  ],
  [
    "3.3.1 - _? [_label_] _value_",
    [
      "",
      "Unwind the call stack from the current function to a given _label_ if _value_ is an error value.",
      "If no _label_ is given only the current function is returned from with the error value.  If there",
      "is no error, the given value is returned.",
      "",
      "The best usecase is, if you just want to hand any errors that might be returned",
      "further upwards the call stack for the parent functions to handle.",
      "",
      "```wlambda",
      "!func = { $e \"this failed!\" };",
      "",
      "!other = {",
      "    # some code ...",
      "",
      "    _? func[]; # If you would not catch the error value here,",
      "               # the program would panic, as an error value",
      "               # must not be ignored!",
      "",
      "    # other code ...",
      "",
      "    panic \"this will never be reached!\";",
      "",
      "    # something here...",
      "};",
      "",
      "std:assert ~ (unwrap_err other[]) == \"this failed!\";",
      "```",
      "",
      "`_?` can take up to 2 arguments. If so, the first argument is interpreted",
      "as jump label. That is handy if you want to jump up multiple call frames:",
      "",
      "```wlambda",
      "!failing_func = { $e :FAIL };",
      "",
      "!func = \\:some_unique_label {",
      "    ( _ == 42 ) {",
      "        std:displayln \"We got 42!\";",
      "",
      "        # The `then` branch we are currently in is a call frame.",
      "        # To jump further up the call stack, we need the label",
      "        # we defined for the function above.",
      "        !val = _? :some_unique_label failing_func[];",
      "",
      "        std:displayln \"Returned:\" val;",
      "    }",
      "};",
      "",
      "std:assert_eq (unwrap_err ~ func 42) :FAIL;",
      "```",
      "",
      "A more elaborate example:",
      "",
      "```wlambda",
      "!do_fail = $false;",
      "",
      "!maybe_fails1 = { 10 };",
      "!maybe_fails2 = {",
      "    do_fail { $error \"something is wrong\" }",
      "            { .do_fail = $true; 2 };",
      "};",
      "",
      "!a = {",
      "    !x = _? maybe_fails1[];",
      "    .x = x + (_? maybe_fails2[]);",
      "    x",
      "};",
      "",
      "!first  = a[];",
      "!second = a[];",
      "",
      "std:assert_eq first 12;",
      "std:assert (is_err second);",
      "```",
      ""
    ]
  ],
  [
    "3.3.2 - unwrap _value_",
    [
      "",
      "Unwraps the given _value_. If the _value_ is an error object it will panic.",
      "Otherwise it will just return the given value. If the _value_ is an optional",
      "value, it will return the value that is wrapped in the optional value.",
      "If it is an empty optional, it will also panic.",
      "",
      "Here an demonstration of the unwrap panic:",
      "",
      "```wlambda",
      "match (std:eval $code { unwrap $e XXX })",
      "    ($e err) => {",
      "        std:assert ~ std:str:find \"Variable 'XXX' undefined\" $\\.err;",
      "    }",
      "    { std:assert $false };",
      "```",
      "",
      "And here how to unwrap optionals:",
      "",
      "```wlambda",
      "std:assert_eq (unwrap $o(123))  123;",
      "",
      "match (std:eval $code { unwrap $o() })",
      "    ($e err) => {",
      "        std:assert ~ std:str:find \"unwrap empty option\" $\\.err;",
      "    }",
      "    { std:assert $false };",
      "```",
      ""
    ]
  ],
  [
    "3.3.3 - unwrap_err _error-value_",
    [
      "",
      "Unwraps an error value. Does panic if _error-value_ is not an error value.",
      "If it is an error value, the inner wrapped value is returned.",
      "",
      "```wlambda",
      "!v = unwrap_err $e \"Some Error\";",
      "",
      "std:assert_eq v \"Some Error\";",
      "```",
      ""
    ]
  ],
  [
    "3.3.4 - on_error _handler_ _maybe-error-value_",
    [
      "",
      "The first parameter to `on_error` should be a _handler_ function,",
      "which will be called with four parameters.",
      "The first of these parameters is the error text,",
      "followed by the line number, column number and file name",
      "from which the error originates.",
      "",
      "The given _handler_ is called when an error value is encountered",
      "as second argument, the _maybe-error-value_.",
      "",
      "An example to demonstrate the handler arguments:",
      "",
      "```wlambda",
      "on_error {!(func, line, col, filename) = @;",
      "    # ...",
      "} ($e \"test\");",
      "```",
      "",
      "A usage example:",
      "",
      "```wlambda",
      "!func = {",
      "    (_ == 13) {",
      "        $e \"this failed!\"",
      "    } {",
      "        \"all ok!\"",
      "    }",
      "};",
      "",
      "!x = $n;",
      "",
      "# The first function of on_error will be called with the unwrapped",
      "# error if an error occured.",
      "on_error {|4| .x = _; } ~ func 13;",
      "std:assert_eq x \"this failed!\";",
      "",
      "!ret = on_error {|4| .x = _; } ~ func 1;",
      "std:assert_eq ret \"all ok!\";",
      "```",
      ""
    ]
  ],
  [
    "3.3.5 - is_err _value_",
    [
      "",
      "Returns `$true` if _value_ is an error value.",
      "",
      "```wlambda",
      "std:assert ~ is_err $e \"foo\";",
      "std:assert ~ not ~ is_err $none;",
      "std:assert ~ not ~ is_err 10;",
      "```",
      ""
    ]
  ],
  [
    "3.3.6 - std:error_to_str _value_",
    [
      "",
      "This function accepts an error value in contrast to `str`, but does",
      "not panic but transform the error value into its string representation.",
      "",
      "```wlambda",
      "!r = std:error_to_str $e \"TEST\";",
      "",
      "std:assert_eq r \"$e \\\"TEST\\\" [@ <wlambda::eval>:1:26 Err]\";",
      "```",
      "",
      "WARNING: The string representation might change between wlambda versions.",
      "Please use `on_error` to access the individual parts",
      "(line, column, filename, error value) of the error.",
      ""
    ]
  ],
  [
    "3.4 - Booleans",
    [
      "",
      "True and false are represented by `$t` and `$f` or `$true` and `$false`,",
      "whatever suits your coding style better.",
      "",
      "You can either use a boolean value with one or two arguments, where `$true`",
      "will call the first argument, and `$false` the second argument. If a second argument",
      "isn't provided and the value is `$false`, `$none` is returned. So to",
      "check for truthness you can just do:",
      "",
      "```wlambda",
      "!x = 10;",
      "!some_num =",
      "    (x == 10) { \"it is ten\" } { \"it is not ten\" };",
      "",
      "std:assert_eq some_num \"it is ten\";",
      "",
      ".x = 20;",
      ".some_num =",
      "    (x == 10) { \"it is ten\" } { \"it is not ten\" };",
      "std:assert_eq some_num \"it is not ten\";",
      "```",
      ""
    ]
  ],
  [
    "3.4.1 - is_bool _any-value_",
    [
      "",
      "You can check if something is a boolean with `is_bool`:",
      "",
      "```wlambda",
      "std:assert ~ is_bool $true;",
      "std:assert ~ is_bool $false;",
      "std:assert ~ not[is_bool $n];",
      "std:assert ~ not[is_bool \"\"];",
      "std:assert ~ not[is_bool 0];",
      "```",
      ""
    ]
  ],
  [
    "3.4.2 - bool _any-value_",
    [
      "",
      "You can cast _any-value_ into a boolean with the `bool` function:",
      "",
      "```wlambda",
      "std:assert_eq (bool 1)          $true;",
      "std:assert_eq (bool 0)          $false;",
      "std:assert_eq (bool $e :x)      $false;",
      "std:assert_eq (bool $n)         $false;",
      "std:assert_eq (bool \"\")         $false;",
      "std:assert_eq (bool \"0\")        $false;",
      "std:assert_eq (bool \"1\")        $true;",
      "std:assert_eq (bool :0)         $false;",
      "std:assert_eq (bool :1)         $true;",
      "std:assert_eq (bool 0.0)        $false;",
      "std:assert_eq (bool 0.1)        $false;",
      "std:assert_eq (bool 1.0)        $true;",
      "std:assert_eq (bool {})         $true;",
      "std:assert_eq (bool $b\"\")       $false;",
      "std:assert_eq (bool $b\"\\x00\")   $false;",
      "std:assert_eq (bool $b\"\\x01\")   $true;",
      "```",
      ""
    ]
  ],
  [
    "3.4.3 - not _value_",
    [
      "",
      "This function negates the boolean _value_. If it is not a boolean, it will",
      "be casted into one before negating.",
      "",
      "```wlambda",
      "std:assert ~ not $false;",
      "std:assert ~ not 0;",
      "std:assert ~ not $none;",
      "```",
      ""
    ]
  ],
  [
    "3.4.4 - Boolean List Indexing",
    [
      "",
      "Booleans can also be used to pick a value from a list",
      "by calling the boolean with a list as first argument:",
      "",
      "```wlambda",
      "std:assert_eq ($true  $[:a, :b]) :b;",
      "std:assert_eq ($false $[:a, :b]) :a;",
      "```",
      ""
    ]
  ],
  [
    "3.5 - 64-Bit Integers",
    [
      "",
      "WLambda's most basic numeric data type is the 64-Bit integer, aka _i64_ in Rust.",
      "Like with other numbers multiple radix literal forms are supported:",
      "",
      "```wlambda",
      "# Decimal:",
      "std:assert_eq 10r99         99;",
      "",
      "# Hexadecimal:",
      "std:assert_eq 0xFF01        65281;",
      "",
      "# Binary:",
      "std:assert_eq  0b1011       11;",
      "std:assert_eq -0b1011      -11;",
      "",
      "# Radix 4:",
      "std:assert_eq 4r31          13;",
      "```",
      ""
    ]
  ],
  [
    "3.5.1 - int _value_",
    [
      "",
      "Returns the integer casted version of _value_.",
      "Mostly interesting for converting a string to an integer (in radix 10)",
      "or for getting the truncated value of a float.",
      "",
      "```wlambda",
      "std:assert_eq (int 4.2)         4;",
      "std:assert_eq (int \"402\")       402;",
      "std:assert_eq (int \"a3\")        0;",
      "",
      "std:assert_eq (int $b\"@\")       0x40;   # Returns the byte value of the first char",
      "",
      "std:assert_eq (int $[4,4,4])    3; # Same as `len`",
      "std:assert_eq (int ${a=4,b=4})  2; # Same as `len`",
      "```",
      ""
    ]
  ],
  [
    "3.5.2 - is_int _value_",
    [
      "",
      "Returns `$true` if _value_ is of data type integer. Otherwise it returns `$false`.",
      ""
    ]
  ],
  [
    "3.5.3 - std:neg_i64 _integer_",
    [
      "",
      "Negates the _integer_, which makes a negative from a positive and positive",
      "from a negative number.",
      "",
      "```wlambda",
      "std:assert_eq (std:neg_i64 -1)      1;",
      "std:assert_eq (std:neg_i64 1)      -1;",
      "",
      "std:assert_eq (std:neg_i64 0xFF)  -255;",
      "```",
      ""
    ]
  ],
  [
    "3.5.4 - std:not_i64 _integer_",
    [
      "",
      "Flips the bits of the signed 64-Bit _integer_.",
      "",
      "```wlambda",
      "std:assert_eq (std:not_i64 -1)      0;",
      "std:assert_eq (std:not_i64 1)      -2;",
      "",
      "std:assert_eq (std:not_i64 0xFF)  -256;",
      "```",
      ""
    ]
  ],
  [
    "3.5.5 - std:neg_u32 _integer_",
    [
      "",
      "Negates the _integer_ as if it was an unsigned 32-Bit integer.",
      "",
      "```wlambda",
      "std:assert_eq (std:neg_u32 0xFF)   4294967041;",
      "std:assert_eq (std:neg_u32 0x1)    4294967295;",
      "std:assert_eq (std:neg_u32 0x0)    0;",
      "```",
      ""
    ]
  ],
  [
    "3.5.6 - std:not_u32 _integer_",
    [
      "",
      "Flips the bits of the _integer_ as if it was an unsigned 32-Bit integer.",
      "",
      "```wlambda",
      "std:assert_eq (std:not_u32 0xFF)   4294967040;",
      "std:assert_eq (std:not_u32 0x1)    4294967294;",
      "std:assert_eq (std:not_u32 0x0)    4294967295;",
      "```",
      ""
    ]
  ],
  [
    "3.6 - 64-Bit Floats",
    [
      "",
      "WLambda supports 64-Bit floating point numbers, aka _f64_ in Rust.",
      "Like with other numbers multiple radix literal forms are supported:",
      "",
      "```wlambda",
      "# Decimal:",
      "std:assert_eq 10r9.92       9.92;",
      "",
      "# Hexadecimal:",
      "std:assert_eq 0xFF.1        255.0625;",
      "",
      "# Binary:",
      "std:assert_eq 0b1011.101    11.625;",
      "",
      "# Radix 4:",
      "std:assert_eq 4r3.3         3.75;",
      "```",
      ""
    ]
  ],
  [
    "3.6.1 - float _value_",
    [
      "",
      "This function casts _value_ into a float:",
      "",
      "```wlambda",
      "",
      "std:assert_eq (float 10)       10.0;",
      "std:assert_eq (float $t)        1.0;",
      "std:assert_eq (float $f)        0.0;",
      "std:assert_eq (float :\"32.2\")  32.2;",
      "std:assert_eq (float \"5.42\")   5.42;",
      "std:assert_eq (float \"5.42\")   5.42;",
      "std:assert_eq (float $b\"\\xFF\") 255.0;",
      "",
      "```",
      ""
    ]
  ],
  [
    "3.6.2 - is_float _value_",
    [
      "",
      "Returns `$true` if _value_ is a float, otherwise `$false` is returned.",
      "",
      "```wlambda",
      "std:assert ~ is_float 4.4;",
      "std:assert ~ is_float 1.0 + 1;",
      "std:assert ~ not ~ is_float 1 + 1.0;",
      "std:assert ~ not ~ is_float 4;",
      "std:assert ~ not ~ is_float $true;",
      "```",
      ""
    ]
  ],
  [
    "3.6.3 - std:num:acos _float_",
    [
      "",
      "Computes the arccosine of a number. Return value is in radians in the range [0,",
      "pi] or NaN if the number is outside the range [-1, 1].",
      ""
    ]
  ],
  [
    "3.6.4 - std:num:acosh _float_",
    [
      "",
      "Inverse hyperbolic cosine function.",
      ""
    ]
  ],
  [
    "3.6.5 - std:num:asin _float_",
    [
      "",
      "Computes the arcsine of a number. Return value is in radians in the range",
      "[-pi/2, pi/2] or NaN if the number is outside the range [-1, 1].",
      ""
    ]
  ],
  [
    "3.6.6 - std:num:asinh _float_",
    [
      "",
      "Inverse hyperbolic sine function.",
      ""
    ]
  ],
  [
    "3.6.7 - std:num:atan _float_",
    [
      "",
      "Computes the arctangent of a number. Return value is in radians in the range",
      "[-pi/2, pi/2].",
      ""
    ]
  ],
  [
    "3.6.8 - std:num:atan2 _y_ _x_",
    [
      "",
      "Computes the four quadrant arctangent of _y_ and other _x_ in radians.",
      "",
      "- x = 0, y = 0: 0",
      "- x >= 0: arctan(y/x) -> [-pi/2, pi/2]",
      "- y >= 0: arctan(y/x) + pi -> (pi/2, pi]",
      "- y < 0: arctan(y/x) - pi -> (-pi, -pi/2)",
      ""
    ]
  ],
  [
    "3.6.9 - std:num:atanh _float_",
    [
      "",
      "Inverse hyperbolic tangent function.",
      ""
    ]
  ],
  [
    "3.6.10 - std:num:cbrt _float_",
    [
      "",
      "Takes the cubic root of a number.",
      ""
    ]
  ],
  [
    "3.6.11 - std:num:ceil _float_",
    [
      "",
      "Returns the smallest integer (still a float) greater than or equal to a number.",
      ""
    ]
  ],
  [
    "3.6.12 - std:num:cos _float_",
    [
      "",
      "Computes the cosine of a number (in radians).",
      ""
    ]
  ],
  [
    "3.6.13 - std:num:cosh _float_",
    [
      "",
      "Hyperbolic cosine function.",
      ""
    ]
  ],
  [
    "3.6.14 - std:num:exp _float_",
    [
      "",
      "Returns e ^ _float_, (the exponential function).",
      ""
    ]
  ],
  [
    "3.6.15 - std:num:exp2 _float_",
    [
      "",
      "Returns 2 ^ _float_.",
      ""
    ]
  ],
  [
    "3.6.16 - std:num:exp_m1 _float_",
    [
      "",
      "Returns (e ^ _float_ - 1) in a way that is accurate even if the number is close",
      "to zero.",
      ""
    ]
  ],
  [
    "3.6.17 - std:num:floor _float_",
    [
      "",
      "Returns the largest integer (still as float) less than or equal to a number.",
      ""
    ]
  ],
  [
    "3.6.18 - std:num:hypot _y_ _x_",
    [
      "",
      "Calculates the length of the hypotenuse of a right-angle triangle given legs of",
      "length _x_ and _y_.",
      ""
    ]
  ],
  [
    "3.6.19 - std:num:ln _float_",
    [
      "",
      "Returns the natural logarithm of the number.",
      ""
    ]
  ],
  [
    "3.6.20 - std:num:log _float_",
    [
      "",
      "Returns the logarithm of the number with respect to an arbitrary base.",
      "",
      "The result may not be correctly rounded owing to implementation details;",
      "`std:log2` can produce more accurate results for base 2, and `std:log10` can",
      "produce more accurate results for base 10.",
      ""
    ]
  ],
  [
    "3.6.21 - std:num:log10 _float_",
    [
      "",
      "Returns the base 10 logarithm of the number.",
      ""
    ]
  ],
  [
    "3.6.22 - std:num:log2 _float_",
    [
      "",
      "Returns the base 2 logarithm of the number.",
      ""
    ]
  ],
  [
    "3.6.23 - std:num:pow _float_",
    [
      "",
      "Raises a number to a floating point power.",
      "You may also use the `^` operator, which also works for integers.",
      ""
    ]
  ],
  [
    "3.6.24 - std:num:recip _float_",
    [
      "",
      "Takes the reciprocal (inverse) of a number, 1/x.",
      ""
    ]
  ],
  [
    "3.6.25 - std:num:round _float_",
    [
      "",
      "Returns the nearest integer (still a float) to a number. Round half-way cases",
      "away from 0.0.",
      ""
    ]
  ],
  [
    "3.6.26 - std:num:sin _float_",
    [
      "",
      "Computes the sine of a number (in radians).",
      ""
    ]
  ],
  [
    "3.6.27 - std:num:sinh _float_",
    [
      "",
      "Hyperbolic sine function.",
      ""
    ]
  ],
  [
    "3.6.28 - std:num:sqrt _float_",
    [
      "",
      "Takes the square root of a number.",
      ""
    ]
  ],
  [
    "3.6.29 - std:num:tan _float_",
    [
      "",
      "Computes the tangent of a number (in radians).",
      ""
    ]
  ],
  [
    "3.6.30 - std:num:tanh _float_",
    [
      "",
      "Hyperbolic tangent function.",
      ""
    ]
  ],
  [
    "3.6.31 - std:num:to_degrees _float_",
    [
      "",
      "Converts radians to degrees.",
      ""
    ]
  ],
  [
    "3.6.32 - std:num:to_radians _float_",
    [
      "",
      "Converts degrees to radians.",
      ""
    ]
  ],
  [
    "3.6.33 - std:num:trunc _float_",
    [
      "",
      "Returns the integer part of a number.",
      ""
    ]
  ],
  [
    "3.6.34 - std:num:lerp _a_ _b_ _x_",
    [
      "",
      "Linear interpolation between _a_ and _b_ by _x_. Where _x_ is",
      "in the range of `[0.0, 1.0]`.",
      "",
      "```wlambda",
      "!res = int ~ std:num:lerp 0.0 100.0 0.5;",
      "",
      "std:assert_eq res 50;",
      "```",
      ""
    ]
  ],
  [
    "3.6.35 - std:num:smoothstep _a_ _b_ _x_",
    [
      "",
      "Interpolates smoothly from 0.0 to 1.0 where _x_ is in the range of `[a, b]`.",
      "",
      "```wlambda",
      "!res = int ~ 1000.0 * (std:num:smoothstep 0.0 100.0 10.0);",
      "",
      "std:assert_eq res 28;",
      "```",
      ""
    ]
  ],
  [
    "3.6.36 - std:num:fract _float_",
    [
      "",
      "Returns the fractional part of the floating point number _float_.",
      "",
      "```wlambda",
      "std:assert ((std:num:fract 4.25) - 0.25) < 0.00001",
      "```",
      ""
    ]
  ],
  [
    "3.7 - Numeric Functions",
    [
      "",
      "These functions work for all types of numbers.",
      ""
    ]
  ],
  [
    "3.7.1 - std:num:abs _number_",
    [
      "",
      "Takes the absolute value of _number_. If _number_ is not a number",
      "it will be converted into an integer.",
      "",
      "```wlambda",
      "std:assert_eq (std:num:abs -10)     10;",
      "std:assert_eq (std:num:abs -13.3)   13.3;",
      "```",
      ""
    ]
  ],
  [
    "3.7.2 - std:num:signum _number_",
    [
      "",
      "Returns either 1 or -1, depending on the sign of the given _number_.",
      "",
      "```wlambda",
      "std:assert_eq (std:num:signum -4)  -1;",
      "std:assert_eq (std:num:signum  4)   1;",
      "",
      "std:assert_eq (std:num:signum -4.0)  -1.0;",
      "std:assert_eq (std:num:signum  4.0)   1.0;",
      "```",
      ""
    ]
  ],
  [
    "3.7.3 - std:num:int_to_closed_open01 _integer_",
    [
      "",
      "Transforms the given 64-Bit _integer_ into a number in the range `0.0` to `1.0`.",
      "Inclusive `0.0`, exclusive `1.0`. This function is mainly useful if you generated",
      "the integer from a random number generator.",
      "",
      "```wlambda",
      "std:assert_rel_eq (std:num:int_to_closed_open01 0)  0.0         0.00000001;",
      "std:assert_rel_eq (std:num:int_to_closed_open01 -1) 0.999999999 0.00000001;",
      "```",
      ""
    ]
  ],
  [
    "3.7.4 - std:num:int_to_open01 _integer_",
    [
      "",
      "Transforms the given 64-Bit _integer_ into a number in the range `0.0` to `1.0`.",
      "Exclusive `0.0`, exclusive `1.0`. This function is mainly useful if you generated",
      "the integer from a random number generator.",
      "",
      "```wlambda",
      "std:assert (std:num:int_to_open01 0)  > 0.0;",
      "std:assert (std:num:int_to_open01 -1) < 1.0;",
      "```",
      ""
    ]
  ],
  [
    "3.7.5 - std:num:int_to_open_closed01 _integer_",
    [
      "",
      "Transforms the given 64-Bit _integer_ into a number in the range `0.0` to `1.0`.",
      "Inclusive `0.0`, inclusive `1.0`. This function is mainly useful if you generated",
      "the integer from a random number generator.",
      "",
      "```wlambda",
      "std:assert (std:num:int_to_open_closed01 0)  > 0.0;",
      "std:assert (std:num:int_to_open_closed01 -1) == 1.0;",
      "```",
      ""
    ]
  ],
  [
    "3.8 - Numerical Mathematical Vectors",
    [
      "",
      "In order to aid in the development of GUIs, games, and other physics/geometry adjacent software,",
      "WLambda comes with a built in datatype for mathematical vectors, which can contain floats and integers",
      "and have between two and four dimensions.",
      "",
      "```wlambda",
      "# integer vectors",
      "std:assert ~ $i(-1, 2).y                == 2;",
      "std:assert ~ (ivec ${z=3})              == $i(0,0,3);",
      "std:assert ~ (ivec4 $[])                == $i(0,0,0,0);",
      "std:assert ~ $i(1.49, -2.72)            == $i(1,-2);",
      "# float vectors",
      "std:assert ~ $f(1.00, -33).x            == $f(1, 200).first;",
      "std:assert ~ $f(-0, 2.4).y              == $f(1.6, 2.4).second;",
      "std:assert ~ (fvec3 ${w=0.1})           == $f(0,0,0);",
      "# conversion",
      "std:assert ~ (fvec3 $i(1, 2))/10        == $f(0.1, 0.2, 0);",
      "std:assert ~ (ivec2 $f(1.3, 2.7, -5.8)) == $i(1, 2);",
      "std:assert ~ (ivec $f(1.3, 2.7, -5.8))  == $i(1, 2, -5);",
      "```",
      ""
    ]
  ],
  [
    "3.8.1 - Vector Conversions",
    [
      "",
      "There are eight functions for converting other values into vectors",
      "and vectors of integers into vectors of floats:",
      "",
      "- `ivec` ",
      "- `ivec2`",
      "- `ivec3`",
      "- `ivec4`",
      "- `fvec`",
      "- `fvec2`",
      "- `fvec3`",
      "- `fvec4`",
      "",
      "The functions without a dimension suffix fill in as many dimensions",
      "as are present in the object being converted.",
      "The functions with dimension suffixes fill in any missing dimensions",
      "with `0`s and ignore dimensions as necessary.",
      "",
      "NOTE: `ivec` will always truncate (i.e. round down) floats into integers when converting,",
      "just like when converting floats into integers implicitly elsewhere in WLambda.",
      ""
    ]
  ],
  [
    "3.8.2 - Vector Component Access",
    [
      "",
      "There are 12 functions for accessing the components of vectors,",
      "but only four have unique behavior (the rest are aliases).",
      "",
      "- `x`/`r`/`h`/`0`/`first`,",
      "- `y`/`g`/`s`/`1`/`second`,",
      "- `z`/`b`/`v`/`2`/`third`,",
      "- `w`/`3`/`fourth`",
      "",
      "```wlambda",
      "!my_vec = $f(39.3, 404.504, 333.8);",
      "std:assert_eq my_vec.x my_vec.0;",
      "std:assert_eq my_vec.x my_vec.first;",
      "",
      "std:assert_eq my_vec.y my_vec.1;",
      "std:assert_eq my_vec.y my_vec.second;",
      "",
      "std:assert_eq my_vec.z my_vec.2;",
      "std:assert_eq my_vec.z my_vec.third;",
      "",
      "std:assert_eq my_vec.w my_vec.3;",
      "std:assert_eq my_vec.w my_vec.fourth;",
      "```",
      ""
    ]
  ],
  [
    "3.8.3 - Named Field Access and Swizzling",
    [
      "",
      "You can access the fields of numeric vectors with different keys:",
      "",
      "```wlambda",
      "std:assert_eq $i(2,3,4,5).x     2;",
      "std:assert_eq $i(2,3,4,5).y     3;",
      "std:assert_eq $i(2,3,4,5).z     4;",
      "std:assert_eq $i(2,3,4,5).w     5;",
      "",
      "std:assert_eq $i(5,6,7,8).r     5;",
      "std:assert_eq $i(5,6,7,8).g     6;",
      "std:assert_eq $i(5,6,7,8).b     7;",
      "std:assert_eq $i(5,6,7,8).a     8;",
      "",
      "std:assert_eq $i(5,6,7,8).h     5;",
      "std:assert_eq $i(5,6,7,8).s     6;",
      "std:assert_eq $i(5,6,7,8).v     7;",
      "std:assert_eq $i(5,6,7,8).a     8;",
      "",
      "std:assert_eq $i(5,6,7,8).0     5;",
      "std:assert_eq $i(5,6,7,8).1     6;",
      "std:assert_eq $i(5,6,7,8).2     7;",
      "std:assert_eq $i(5,6,7,8).3     8;",
      "```",
      "",
      "You can also use **swizzling** to quickly make a new vector:",
      "",
      "```wlambda",
      "std:assert_eq $i(2,3,4).xx      $i(2,2);",
      "std:assert_eq $i(2,3,4).xyxz    $i(2,3,2,4);",
      "std:assert_eq $i(2,3,4).bgr     $i(4,3,2);",
      "std:assert_eq $i(2,3).xyrg      $i(2,3,2,3);",
      "std:assert_eq $i(2,3,4,5).zw    $i(4,5);",
      "```",
      "",
      ""
    ]
  ],
  [
    "3.8.4 - Euler Addition/Subtraction",
    [
      "",
      "You can add vectors to each other and subtract them from each other.",
      "",
      "The type of the resulting vector will be the same as the vector on the left.",
      "",
      "The number of dimensions in the resulting vector will be the same as the vector",
      "with the highest number of dimensions that was involved in the operation.",
      "",
      "If the value on the right isn't a vector, it will be converted into one,",
      "just as if it were passed through `ivec` or `fvec`, meaning that as many",
      "dimensions are kept as are present.",
      "",
      "```wlambda",
      "std:assert_eq[ $i(0.1, 0.9) + $i(1, 0) , $i(1, 0) ];",
      "std:assert_eq[ $f(0.1, 0.9) + $i(1, 0) , $f(1.1, 0.9) ];",
      "std:assert_eq[ $f(0.1, 0.9) + ${ w=7 } , $f(0.1, 0.9, 0, 7) ];",
      "std:assert_eq[ std:v:mag2 $i(-1, 5) + $i(1, -5) , 0.0 ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.5 - Scalar Multiplication/Division",
    [
      "",
      "You can multiply and divide integer and float vectors by single numbers.",
      "This copies the vector, multiplies or divides each component of the vector by the single number,",
      "and returns the result.",
      "",
      "NOTE: Dividing `ivec`s will always truncate (i.e. round down) floats into integers.",
      "",
      "```wlambda",
      "std:assert ~ $i(3, 6)/2       == $i(1, 3);",
      "std:assert ~ $f(3, 6)/2       == $f(1.5, 3);",
      "std:assert ~ $f(0.5, 0) * 1.3 == $f(0.65,0);",
      "std:assert ~ (std:v:mag (std:v:norm $[40.19, 0.399]) * 10) == 10.0;",
      "```",
      ""
    ]
  ],
  [
    "3.8.6 - Unary Vector Operations",
    [
      "",
      "Calling `-` on a vector returns a new vector with all of its fields negated.",
      "This is equivalent to multiplying the vector by `-1`.",
      "",
      "Calling `+` on a vector returns a copy of the exact same vector.",
      "This is equivalent to multiplying the vector by `1`.",
      "",
      "```wlambda",
      "!my_vec = $f(1.2, 2.3, 3.4);",
      "std:assert_eq (ivec (-my_vec)) $i(-1, -2, -3);",
      "std:assert_eq (+my_vec) my_vec;",
      "# adding something to its inverse yields all 0s",
      "std:assert_eq[ my_vec + (-my_vec), my_vec * 0 ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.7 - is_fvec _value_",
    [
      "",
      "Returns `$true` if _value_ is a float vector.",
      "",
      "```wlambda",
      "std:assert_eq   (is_fvec $f(1,2))       $true;",
      "std:assert_eq   (is_fvec $f(1,2,3))     $true;",
      "std:assert_eq   (is_fvec $f(1,2,3,4))   $true;",
      "std:assert_eq   (is_fvec $none)         $false;",
      "std:assert_eq   (is_fvec $i(1,2))       $false;",
      "std:assert_eq   (is_fvec $[3.4, 4.5])   $false;",
      "",
      "std:assert_eq   (is_fvec fvec <& $[3.4, 4.5])   $true;",
      "",
      "# References are not dereferenced:",
      "std:assert_eq   (is_fvec $&&$f(3,4))    $false;",
      "std:assert_eq   (is_fvec $*$&&$f(3,4))  $true;",
      "```",
      ""
    ]
  ],
  [
    "3.8.8 - is_ivec _value_",
    [
      "",
      "Returns `$true` if _value_ is an integer vector.",
      "",
      "```wlambda",
      "std:assert_eq   (is_ivec $i(1,2))       $true;",
      "std:assert_eq   (is_ivec $i(1,2,3))     $true;",
      "std:assert_eq   (is_ivec $i(1,2,3,4))   $true;",
      "std:assert_eq   (is_ivec $none)         $false;",
      "std:assert_eq   (is_ivec $[3, 4])       $false;",
      "",
      "std:assert_eq   (is_ivec ivec <& $[3.4, 4.5])   $true;",
      "",
      "# References are not dereferenced:",
      "std:assert_eq   (is_ivec    $&& $i(3,4))  $false;",
      "std:assert_eq   (is_ivec $* $&& $i(3,4))  $true;",
      "```",
      ""
    ]
  ],
  [
    "3.8.9 - is_nvec _value_",
    [
      "",
      "Returns `$true` if _value_ is either a numerical float or integer vector.",
      "",
      "```wlambda",
      "std:assert_eq   (is_nvec $i(1,2))       $true;",
      "std:assert_eq   (is_nvec $i(1,2,3))     $true;",
      "std:assert_eq   (is_nvec $i(1,2,3,4))   $true;",
      "std:assert_eq   (is_nvec $f(1,2))       $true;",
      "std:assert_eq   (is_nvec $f(1,2,3))     $true;",
      "std:assert_eq   (is_nvec $f(1,2,3,4))   $true;",
      "std:assert_eq   (is_nvec $none)         $false;",
      "std:assert_eq   (is_nvec $[3, 4])       $false;",
      "",
      "std:assert_eq   (is_nvec fvec <& $[3.4, 4.5])   $true;",
      "std:assert_eq   (is_nvec ivec <& $[3.4, 4.5])   $true;",
      "```",
      ""
    ]
  ],
  [
    "3.8.10 - nvec_len _value_",
    [
      "",
      "Returns the length of a numerical vector, commonly known as the dimension.",
      "Either 2, 3 or 4.",
      "",
      "```wlambda",
      "std:assert_eq (nvec_len $i(1, 2))       2;",
      "std:assert_eq (nvec_len $i(1, 2, 3))    3;",
      "std:assert_eq (nvec_len $i(1, 2, 3, 4)) 4;",
      "",
      "std:assert_eq (nvec_len $f(1.1, 2.2))           2;",
      "std:assert_eq (nvec_len $f(1.1, 2.2, 3.3))      3;",
      "std:assert_eq (nvec_len $f(1.1, 2.2, 3.3, 4.4)) 4;",
      "```",
      ""
    ]
  ],
  [
    "3.8.11 - fvec _value_",
    [
      "",
      "Will cast _value_ into a float vector. You can cast a multitude of data types",
      "into a float vector:",
      "",
      "```wlambda",
      "std:assert_eq   (fvec  $[1,2,3,4])      $f(1,2,3,4);",
      "std:assert_eq   (fvec  $[1,2,3])        $f(1,2,3);",
      "std:assert_eq   (fvec  $[1,2])          $f(1,2);",
      "",
      "std:assert_eq   (fvec $i(1,2))          $f(1,2);",
      "std:assert_eq   (fvec $i(1,2,3))        $f(1,2,3);",
      "std:assert_eq   (fvec $i(1,2,3,4))      $f(1,2,3,4);",
      "",
      "std:assert_eq   (fvec $p(\"2\", \"3.4\"))   $f(2,3.4);",
      "",
      "!i = $iter $[] +> $p(3,4) +> $[5,6];",
      "std:assert_eq   (fvec i)    $f(3,4);",
      "std:assert_eq   (fvec i)    $f(5,6);",
      "",
      "std:assert_eq   (fvec ${x = 1, y = 2})                 $f(1,2);",
      "std:assert_eq   (fvec ${x = 1, y = 2, z = 3})          $f(1,2,3);",
      "std:assert_eq   (fvec ${x = 1, y = 2, z = 3, w = 4})   $f(1,2,3,4);",
      "```",
      ""
    ]
  ],
  [
    "3.8.12 - fvec2 _value_",
    [
      "",
      "Like `fvec` but always returns a 2 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (fvec2 $i(3,4,5))    $f(3,4);",
      "std:assert_eq  (fvec2 $[4,5,6,7,8]) $f(4,5);",
      "",
      "std:assert_eq  (fvec2 ${x = 1, y = 2, z = 3, w = 4})   $f(1,2);",
      "```",
      ""
    ]
  ],
  [
    "3.8.13 - fvec3 _value_",
    [
      "",
      "Like `fvec` but always returns a 3 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (fvec3 $i(3,4,5))    $f(3,4,5);",
      "std:assert_eq  (fvec3 $[4,5,6,7,8]) $f(4,5,6);",
      "",
      "std:assert_eq  (fvec3 ${x = 1, y = 2, z = 3, w = 4})   $f(1,2,3);",
      "```",
      ""
    ]
  ],
  [
    "3.8.14 - fvec4 _value_",
    [
      "",
      "Like `fvec` but always returns a 4 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (fvec4 $i(3,4,5))    $f(3,4,5,0);",
      "std:assert_eq  (fvec4 $[4,5,6,7,8]) $f(4,5,6,7);",
      "",
      "std:assert_eq  (fvec4 ${x = 1, y = 2, z = 3, w = 4})   $f(1,2,3,4);",
      "```",
      ""
    ]
  ],
  [
    "3.8.15 - ivec _value_",
    [
      "",
      "Will cast _value_ into a float vector. You can cast a multitude of data types",
      "into a float vector:",
      "",
      "```wlambda",
      "std:assert_eq   (ivec  $[1,2,3,4])      $i(1,2,3,4);",
      "std:assert_eq   (ivec  $[1,2,3])        $i(1,2,3);",
      "std:assert_eq   (ivec  $[1,2])          $i(1,2);",
      "",
      "std:assert_eq   (ivec $f(1.1,2.1))          $i(1,2);",
      "std:assert_eq   (ivec $f(1.1,2.1,3.2))      $i(1,2,3);",
      "std:assert_eq   (ivec $f(1.1,2.1,3.2,4))    $i(1,2,3,4);",
      "",
      "std:assert_eq   (ivec $p(\"2\", \"3\"))   $i(2,3);",
      "",
      "!i = $iter $[] +> $p(3,4) +> $[5,6];",
      "std:assert_eq   (ivec i)    $i(3,4);",
      "std:assert_eq   (ivec i)    $i(5,6);",
      "",
      "std:assert_eq   (ivec ${x = 1, y = 2})                 $i(1,2);",
      "std:assert_eq   (ivec ${x = 1, y = 2, z = 3})          $i(1,2,3);",
      "std:assert_eq   (ivec ${x = 1, y = 2, z = 3, w = 4})   $i(1,2,3,4);",
      "```",
      ""
    ]
  ],
  [
    "3.8.16 - ivec2 _value_",
    [
      "",
      "Like `ivec` but always returns a 2 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (ivec2 $f(3,4,5))    $i(3,4);",
      "std:assert_eq  (ivec2 $[4,5,6,7,8]) $i(4,5);",
      "",
      "std:assert_eq  (ivec2 ${x = 1, y = 2, z = 3, w = 4})   $i(1,2);",
      "```",
      ""
    ]
  ],
  [
    "3.8.17 - ivec3 _value_",
    [
      "",
      "Like `ivec` but always returns a 3 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (ivec3 $f(3,4,5))    $i(3,4,5);",
      "std:assert_eq  (ivec3 $[4,5,6,7,8]) $i(4,5,6);",
      "",
      "std:assert_eq  (ivec3 ${x = 1, y = 2, z = 3, w = 4})   $i(1,2,3);",
      "```",
      ""
    ]
  ],
  [
    "3.8.18 - ivec4 _value_",
    [
      "",
      "Like `ivec` but always returns a 4 dimensional vector.",
      "",
      "```wlambda",
      "std:assert_eq  (ivec4 $f(3,4,5))    $i(3,4,5,0);",
      "std:assert_eq  (ivec4 $[4,5,6,7,8]) $i(4,5,6,7);",
      "",
      "std:assert_eq  (ivec4 ${x = 1, y = 2, z = 3, w = 4})   $i(1,2,3,4);",
      "```",
      ""
    ]
  ],
  [
    "3.8.19 - std:v:dims _vec_",
    [
      "",
      "You can use this function to retrieve the number of dimensions in _vec_.",
      "",
      "Like most other std:v functions,",
      "it will coerce whatever value is passed into it into a `ivec`,",
      "if that value is not a `fvec`.",
      "",
      "This function always returns an integer, regardless of whether an `ivec` or `fvec` is passed in.",
      "",
      "```wlambda",
      "# the least number of dimensions a vector can have is 2.",
      "std:assert_eq (std:v:dims $[]) 2;",
      "# while the most is 4.",
      "std:assert_eq (std:v:dims ${w=0}) 4;",
      "std:assert_eq (std:v:dims $f(1,2)) (std:v:dims $i(1,2));",
      "```",
      ""
    ]
  ],
  [
    "3.8.20 - std:v:mag2 _vec_",
    [
      "",
      "Returns the magnitude of _vec_, squared.",
      "",
      "Calculating the squared magnitude is a little bit faster,",
      "so you should prefer this method where performance is paramount.",
      "",
      "The magnitude is always a float, regardless of whether the parameter is an `ivec` or `fvec`.",
      "",
      "```wlambda",
      "std:assert_eq (std:v:mag2 ${w=4}) 16.0;",
      "```",
      ""
    ]
  ],
  [
    "3.8.21 - std:v:mag _vec_",
    [
      "",
      "Returns the magnitude (also known as the length) of _vec_.",
      "",
      "The magnitude is always a float, regardless of whether the parameter is an `ivec` or `fvec`.",
      "",
      "```wlambda",
      "std:assert_eq (std:v:mag ${w=4}) 4.0;",
      "```",
      ""
    ]
  ],
  [
    "3.8.22 - std:v:norm _vec_",
    [
      "",
      "Returns a new vector which has a magnitude of `1`, but points in the same direction as _vec_.",
      "Vectors with a length of one are also known as unit vectors.",
      "",
      "Note that this still returns an `ivec` when used on `ivec`s,",
      "meaning that when used on an `ivec2` only four values are possible:",
      "- `$i(1, 0)`",
      "- `$i(-1, 0)`",
      "- `$i(0, 1)`",
      "- `$i(0, -1)`",
      "",
      "These are the only `ivec2`s that have a length of `1`.",
      "",
      "```wlambda",
      "!p1 = fvec ${ x = 20, y = 30.5 };",
      "!p2 = fvec ${ x = -10, y = 0.5 };",
      "",
      "# get the delta representing how far you'd have to travel to get from p1 to p2",
      "!delta = p2 - p1;",
      "# the normalized delta represents a single 1 sized step you could take to get to p2 from p1.",
      "!n = std:v:norm delta;",
      "",
      "# the length of this step is reflected in the magnitude of the vectors",
      "std:assert_eq[ (std:v:mag delta) - 1, std:v:mag (p1 + n) - p2 ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.23 - std:v:dot _vec1_ _vec2_",
    [
      "",
      "Returns the sum of all components after multiplying each component",
      "in _vec1_ with the corresponding component of _vec2_.",
      "",
      "This can be used to represent the \"sameness\" of two vectors (especially unit vectors):",
      "the degree to which they are pointing in the same direction.",
      "",
      "Returns an integer when used on an `ivec`, and a float when used on an `fvec`.",
      "",
      "If _vec1_ is an `fvec`, then _vec2_ will also be coerced into one.",
      "If _vec1_ isn't an `fvec`, then it's coerced into an `ivec`, just like the other `std:v` functions.",
      "",
      "```wlambda",
      "!at      = fvec ${ x = 20 , y = 30.5 };           # where you're at",
      "!goal    = fvec ${ x = -10, y = 0.5  };           # where you want to look",
      "!looking = std:v:rad2vec (std:num:to_radians 90); # direction you're looking in",
      "",
      "# do you need to turn left or right to look at `goal`,",
      "# if you're standing at `at` looking in `looking`?",
      "",
      "# find the unit vector representing the space between where you want to look and where you're at.",
      "!delta = std:v:norm goal - at;",
      "",
      "# the direction you need to turn in can be found by checking the sign of",
      "# the dot product of where you're currently looking and where you're at.",
      "!dir = std:v:dot delta looking;",
      "",
      "std:assert_eq[ (dir < 0) \"left\" \"right\", \"left\" ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.24 - std:v:cross _vec1_ _vec2_",
    [
      "",
      "Returns a vector perpendicular to _vec1_ and _vec2_.",
      "",
      "Similar to the dot product, but instead of returning a single value it returns another vector,",
      "and is only useful in three (and seven, but WLambda's vectors don't support so many) dimensions.",
      "",
      "Regardless of the number of dimensions in the input vectors, this function will return a 3d vector.",
      "",
      "```wlambda",
      "!x = fvec ${x=1};",
      "!y = fvec ${y=1};",
      "",
      "# the cross product of these two values will represent the third axis, z, and will be",
      "# perpendicular to both other vectors.",
      "",
      "!z = std:v:cross x y;",
      "",
      "std:assert_eq z (fvec ${z=1});",
      "",
      "# because all three vectors are perpindicular, they'll all have the same dot product from each other.",
      "std:assert_eq[(std:v:dot x y), (std:v:dot y z)];",
      "std:assert_eq[(std:v:dot y z), (std:v:dot z x)];",
      "```",
      ""
    ]
  ],
  [
    "3.8.25 - std:v:lerp _vec1_ _vec2_ _t_",
    [
      "",
      "`lerp` stands for linear interpolation.",
      "This function is useful when animating positions, whereas slerp is useful for animating rotations.",
      "",
      "Creates a new vector in a new position relative to _vec1_ and _vec2_.",
      "Aside from the two reference vectors, this function also takes a variable, _t_,",
      "which represents how far relative to the first and second vector the new vector should be.",
      "",
      "If _t_ is `0`, _vec1_ is returned. If _t_ is `1`, then _vec2_ is returned.",
      "If _t_ is `0.5`, the resulting vector will be halfway in between the first and second vector.",
      "",
      "```wlambda",
      "std:assert_eq[ std:v:lerp $f(1,0) $f(0,1) 0.5 , $f(0.5, 0.5) ];",
      "std:assert_eq[ std:v:lerp $f(5,10) ${y=10} 0.75 , $f(1.25, 10) ];",
      "std:assert_eq[ std:v:lerp $[-2,5] $[2,-5] 0.5 , $i(0, 0) ];",
      "!a = $f(83, -49.5);",
      "std:assert_eq[ (std:v:mag a) / 2 , std:v:mag (std:v:lerp a $[] 0.5) ];",
      "std:assert_eq[ (std:v:mag a) * 2 , std:v:mag (std:v:lerp $f(0,0) a 2.0) ];",
      "!b = $f(-484.58, -19);",
      "std:assert_eq[ std:v:lerp b a 1.5 , std:v:lerp a b -0.5 ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.26 - std:v:slerp _vec1_ _vec2_ _t_",
    [
      "",
      "`slerp` stands for spherical linear interpolation.",
      "This function is useful when animating rotations, whereas lerp is useful for animating positions.",
      "",
      "In most cases, you'll want to pass in unit vectors representing rotations to slerp.",
      "You should get back unit vectors in the vast majority of cases,",
      "but if perfect accuracy is required normalizing the output of this function is suggested.",
      "",
      "Creates a new vector in a new position relative to _vec1_ and _vec2_.",
      "Aside from the two reference vectors, this function also takes a variable, _t_,",
      "which represents how far relative to the first and second vector the new vector should be.",
      "",
      "If _t_ is `0`, _vec1_ is returned. If _t_ is `1`, then _vec2_ is returned.",
      "If _t_ is `0.5`, the resulting vector will be halfway in between _vec1_ and _vec2_.",
      "",
      "```wlambda",
      "# compare this to the one for std:v:lerp! note that the length of this one is almost 1.",
      "# this is definitely not the case for std:v:lerp's output with the same input.",
      "!v = std:v:slerp $f(1,0) $f(0,1) 0.5;",
      "# the values may not be exact because of floating point rounding errors,",
      "# but they should be pretty close.",
      "std:assert_rel_eq v.x 0.7071067811865476 0.000001;",
      "std:assert_rel_eq v.y 0.7071067811865476 0.000001;",
      "",
      "# The values are interpolated around a circle, so if you raise t high enough you'll start",
      "# getting the same values as you get with a lower t, although not quite because of float rounding.",
      "!half = (std:v:slerp $f(1,0) $f(0,1) 0.5);",
      "!four = (std:v:slerp $f(1,0) $f(0,1) 4.5);",
      "std:assert_rel_eq half.x four.x 0.000001;",
      "std:assert_rel_eq half.y four.y 0.000001;",
      "```",
      ""
    ]
  ],
  [
    "3.8.27 - std:v:vec2rad _vec_",
    [
      "",
      "Creates a rotation in radians from the x and y components of _vec_.",
      "",
      "Always returns a float.",
      "",
      "Coerces the argument into an `ivec` unless it's a `fvec`.",
      "",
      "```wlambda",
      "std:assert_eq[ std:num:to_degrees (std:v:vec2rad ${x=1}) , 0.0 ];",
      "std:assert_eq[ std:num:to_degrees (std:v:vec2rad ${y=1}) , 90.0 ];",
      "",
      "# halfway in between 0.0 and 90.0 should be 45.",
      "# note that lerp would work here as well",
      "!h = std:v:slerp $f(1, 0) $f(0, 1) 0.5;",
      "std:assert_eq[ std:num:to_degrees (std:v:vec2rad h) , 45.0 ];",
      "```",
      ""
    ]
  ],
  [
    "3.8.28 - std:v:rad2vec _radians_",
    [
      "",
      "Creates a unit vector from _radians_.",
      "",
      "Always returns an `fvec`.",
      "",
      "```wlambda",
      "std:assert_eq[ std:v:rad2vec (std:num:to_radians 0.0) , $f(1, 0)];",
      "std:assert_eq[ ivec (std:v:rad2vec (std:num:to_radians 90.0)), $i(0, 1)];",
      "",
      "# halfway in between 0.0 and 90.0 should be 45.",
      "# note that lerp would NOT work here as well, rad2vec returns a unit vector.",
      "!h = std:v:slerp $f(1, 0) $f(0, 1) 0.5; # slerp because rotations",
      "!r = std:v:rad2vec (std:num:to_radians 45.0);",
      "std:assert_rel_eq r.x h.x 0.0001;",
      "std:assert_rel_eq r.y h.y 0.0001;",
      "```",
      ""
    ]
  ],
  [
    "3.9 - Characters and Bytes",
    [
      "",
      "WLambda has a data type for single characters and bytes. The lexical syntax is",
      "a character or escape sequence delimited by `'`:",
      "",
      "```wlambda",
      "std:assert_eq (type 'a')   \"char\";",
      "std:assert_eq (type $b'a') \"byte\";",
      "",
      "std:assert_eq (type '\\u{40}') \"char\";",
      "std:assert_eq (type $b'\\x40') \"byte\";",
      "",
      "# You can use the unicode escapes up to the first 256 code points in bytes too:",
      "std:assert_eq (char $b'\\u{40}') '\\u{40}';",
      "",
      "# Beyond that, you will get the byte '?':",
      "std:assert_eq (char $b'\\u{3131}') '?';",
      "```",
      "",
      "The can be used interchangeably almost everywhere. They can often also be used",
      "instead of a string, because they are handled like a single character long string.",
      "",
      "They are useful because they do not require an extra allocation in the background.",
      "They are not boxed like strings:",
      "",
      "```wlambda",
      "std:assert_eq (\"foo\" $p(0, 1))  \"f\"; # requires allocation",
      "std:assert_eq (\"foo\".0)         'f'; # requires NO allocation",
      "```",
      ""
    ]
  ],
  [
    "3.9.1 - byte _value_",
    [
      "",
      "Converts the _value_ to a byte. If _value_ is a number, it must be",
      "below or equal to 255, otherwise it will result in the byte `'?'`.",
      "",
      "```wlambda",
      "std:assert_eq (byte 64)           $b'@';",
      "std:assert_eq (byte 300)          $b'?';",
      "std:assert_eq (byte \"ABC\")        $b'A';",
      "std:assert_eq (byte $b\"\\xFF\\xF0\") $b'\\xFF';",
      "std:assert_eq (byte \"\\xFF\\xF0\")   $b'\\xC3'; # first byte of an utf-8 sequence!",
      "```",
      ""
    ]
  ],
  [
    "3.9.2 - char _value_",
    [
      "",
      "Converts the _value_ to a Unicode character.",
      "",
      "```wlambda",
      "std:assert_eq (char $b'\\xFF') 'ÿ';",
      "std:assert_eq (char 0x262F)   '☯';",
      "std:assert_eq (char \"☯xyz\")   '☯';",
      "```",
      ""
    ]
  ],
  [
    "3.9.3 - is_byte _value_",
    [
      "",
      "Checks if _value_ is of the byte data type.",
      "",
      "```wlambda",
      "std:assert (is_byte $b'X');",
      "std:assert not[is_byte 'X'];",
      "std:assert not[is_byte 123];",
      "std:assert (is_byte $b\"abc\".0);",
      "std:assert not[is_byte \"abc\".0];",
      "std:assert not[is_byte $b\"abc\"];",
      "```",
      ""
    ]
  ],
  [
    "3.9.4 - is_char _value_",
    [
      "",
      "Check if _value_ is of the Unicode character data type.",
      "",
      "```wlambda",
      "std:assert (is_char 'X');",
      "std:assert not[is_char $b'X'];",
      "std:assert not[is_char 123];",
      "std:assert (is_char \"abc\".0);",
      "std:assert not[is_char $b\"abc\".0];",
      "std:assert not[is_char $b\"abc\"];",
      "std:assert not[is_char \"abc\"];",
      "```",
      ""
    ]
  ],
  [
    "3.9.5 - std:char:to_lowercase _value_",
    [
      "",
      "Turns the _value_ into a lower case Unicode character.",
      "",
      "```wlambda",
      "std:assert_eq (std:char:to_lowercase 'A') 'a';",
      "std:assert_eq (std:char:to_lowercase 65)  'a';",
      "```",
      ""
    ]
  ],
  [
    "3.9.6 - std:char:to_uppercase _value_",
    [
      "",
      "Turns the _value_ into an upper case Unicode character.",
      "",
      "```wlambda",
      "std:assert_eq (std:char:to_uppercase 'a') 'A';",
      "std:assert_eq (std:char:to_uppercase 97)  'A';",
      "```",
      ""
    ]
  ],
  [
    "3.10 - Strings",
    [
      "",
      "Strings in WLambda are like Rust UTF-8 encoded immutable Unicode strings.",
      "There are two types of literal forms for strings:",
      "",
      "```wlambda",
      "\"abc def \\\"foo\\\"\";",
      "std:assert_eq $q/any delimiter may be used instead of/",
      "    \"any delimiter may be used instead of\";",
      "# Unicode escapes are also working:",
      "std:assert_eq \"\\u{2211}\" \"∑\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.1 - String Literal Syntaxes",
    [
      "",
      "There are multiple kinds of syntax constructs you can use to",
      "notate string (and byte vector) literals:",
      "",
      "- Regular strings",
      "```wlambda",
      "!s = \"a b c\";",
      "",
      "std:assert_eq s \"a b c\";",
      "```",
      "- Byte vectors `$b\"\\x02FOO\\x03\"`",
      "- Quoted strings `$q(123433)`",
      "- Quoted byte vectors `$Q(XZY)`",
      "- WLambda code strings",
      "```wlambda",
      "# Short form $c works too.",
      "!code = $code {",
      "    !this = is a block;",
      "    It just needs to be in valid WLambda[:Syntax];",
      "    .x = But it does not need to pass the compiler",
      "        phase.x;",
      "};",
      "",
      "# Primary use case is `eval` and `std:thread:spawn`:",
      "!v = (std:thread:spawn $code {",
      "    !@import std std;",
      "    !res = \"x\" \"y\" \"z\";",
      "    std:str:cat res 33;",
      "}).join[];",
      "",
      "std:assert_eq v \"xyz33\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.2 - str _value_",
    [
      "",
      "Casts _value_ to a string and returns it.",
      "Also dereferences a value.",
      "",
      "```wlambda",
      "std:assert_eq (str \"\\xFF\")     \"ÿ\";",
      "std:assert_eq (str \"\\x0A\")     \"\\n\";",
      "std:assert_eq (str 1)          \"1\";",
      "std:assert_eq (str $n)         \"\";",
      "std:assert_eq (str $t)         \"$true\";",
      "std:assert_eq (str $f)         \"$false\";",
      "std:assert_eq (str $&10)       \"10\";",
      "std:assert_eq (str $&&10)      \"10\";",
      "std:assert_eq (str ${a=10})    \"${a=10}\";",
      "std:assert_eq (str $[1,2,3])   \"$[1,2,3]\";",
      "std:assert_eq (str $o(42))     \"42\";",
      "std:assert_eq (str $o())       \"\";",
      "",
      "!x = $&&10;",
      "std:assert_eq (str ~ std:ref:weaken x)   \"10\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.3 - std:write_str _value_",
    [
      "",
      "Writes a WLambda syntax representation of the given _value_ to a string.",
      "This is useful for debugging purposes or in combination with `std:eval`.",
      "",
      "",
      "```wlambda",
      "std:assert_eq (std:write_str \"foo\")         \"\\\"foo\\\"\";",
      "std:assert_eq (std:write_str $&&10)         \"$&&10\";",
      "std:assert_eq (std:write_str $[1, 2, 3])    \"$[1,2,3]\"",
      "```",
      "",
      "Here an example in combination with `std:eval`:",
      "",
      "```wlambda",
      "!code =",
      "    std:str:cat",
      "        \"$@i iter i \"",
      "        (std:write_str $[1, 2, 3, 4])",
      "        \" { $+ i }\";",
      "",
      "std:assert_eq (std:eval code) 10;",
      "```",
      ""
    ]
  ],
  [
    "3.10.4 - is_str _value_",
    [
      "",
      "Returns `$true` if _value_ is a string.",
      "",
      "```wlambda",
      "std:assert ~ is_str \"foo\";",
      "",
      "std:assert ~ not ~ is_str $b\"foo\";",
      "std:assert ~ not ~ is_str :foo;",
      "std:assert ~ not ~ is_str 324;",
      "",
      "std:assert ~ not ~ is_str $&&\"foo\";",
      "std:assert ~ is_str $*$&&\"foo\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.5 - std:str:cat _a_ _b_ ...",
    [
      "",
      "Stringifies (like with `str`) and concatenates all its arguments.",
      "If an argument is a vector, it's elements will be stringified and concatenated.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:cat :a 10 23.2 \"ab\" \"cd\" $[1, 2, 3])",
      "    \"a1023.2abcd123\";",
      "```",
      "",
      "If a vector argument is given, it's elements are stringified, thats",
      "useful if you prepare substrings to be concatenated in one single action:",
      "",
      "```wlambda",
      "!out = $[];",
      "std:push out \"abc\";",
      "std:push out \"123\";",
      "std:push out \"XXX\";",
      "",
      "!s = std:str:cat out;",
      "std:assert_eq s \"abc123XXX\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.6 - std:str:join _sep_ _vector_",
    [
      "",
      "Join's the stringified elements of _vector_ with the _sep_ string.",
      "Will return an error if _vector_ is not a vector.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:join \"::\" $[1,2,3])",
      "    \"1::2::3\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.7 - std:str:len _value_",
    [
      "",
      "Returns the length of the stringified _value_ in unicode characters.",
      "The core function `len` does return the number of bytes in the string",
      "instead.",
      "",
      "```wlambda",
      "std:assert_eq (len         \"∑\") 3;",
      "std:assert_eq (std:str:len \"∑\") 1;",
      "std:assert_eq (len         \"∑ÄÄ\") 7;",
      "std:assert_eq (std:str:len \"∑ÄÄ\") 3;",
      "std:assert_eq (len         \"abcd\") 4;",
      "std:assert_eq (std:str:len \"abcd\") 4;",
      "```",
      ""
    ]
  ],
  [
    "3.10.8 - std:str:find _pattern_ _string_ [_offset_]",
    [
      "",
      "Searches for the string _pattern_ in the _string_ and returns the 0 based position",
      "in the string the given _pattern_ starts.",
      "If no pattern was found `$none` is returned.",
      "",
      "```wlambda",
      "std:assert_eq (std:str:find \"xyz\" \"abcxyz\")         3;",
      "std:assert_eq (std:str:find \"xyz\" \"abcxyzxyz\" 6)    6;",
      "std:assert_eq (std:str:find \"xyz\" \"abcxyzfooxyz\" 6) 9;",
      "```",
      ""
    ]
  ],
  [
    "3.10.9 - std:str:replace _pattern_ _replacement_ _string_",
    [
      "",
      "Replaces every occurence of _pattern_ in _string_ with _replacement_",
      "and returns a new string. All values will be casted to a string if",
      "they aren't.",
      "",
      "```wlambda",
      "!s = std:str:replace \"dog\" \"cat\"",
      "    \"I really like my dog, because when you dog, you can put dog in the dog!\";",
      "std:assert_eq s",
      "    \"I really like my cat, because when you cat, you can put cat in the cat!\";",
      "",
      "!s = std:str:replace \"9\" \"1\" \"9999\";",
      "std:assert_eq s \"1111\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.10 - std:str:replace_n _pattern_ _replacement_ _count_ _string_",
    [
      "",
      "Replaces _count_ occurences of _pattern_ in _string_ with _replacement_",
      "and returns a new string. All values will be casted to a string if",
      "they aren't.",
      "",
      "```wlambda",
      "!s = std:str:replace_n \"dog\" \"cat\" 2",
      "    \"I really like my dog, because when you dog, you can put dog in the dog!\";",
      "std:assert_eq s",
      "    \"I really like my cat, because when you cat, you can put dog in the dog!\";",
      "",
      "!s = std:str:replace_n \"9\" \"1\" 3 \"9999\";",
      "std:assert_eq s \"1119\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.11 - std:str:trim _value_",
    [
      "",
      "Trims off any (unicode) white space from the start and end of the",
      "stringified _value_.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:trim \"\\nfooo bar \")",
      "    \"fooo bar\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.12 - std:str:trim_start _value_",
    [
      "",
      "Trims off any (unicode) white space from the start of the stringified _value_.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:trim_start \"  \\nfooo bar \\n\")",
      "    \"fooo bar \\n\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.13 - std:str:trim_end _value_",
    [
      "",
      "Trims off any (unicode) white space from the end of the stringified _value_.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:trim_end \"  \\nfooo bar \\n\")",
      "    \"  \\nfooo bar\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.14 - std:str:pad_start _len_ _pad-str_ _value_",
    [
      "",
      "Pads the stringified _value_ by _pad-str_ up to _len_ characters, inserting",
      "at the start of the string.",
      "The output string is guaranteed to be exactly _len_ unicode characters",
      "long and not longer. If _pad-str_ is empty, nothing is done.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:pad_start 2 \"Ä\" \"0\")",
      "    \"Ä0\";",
      "std:assert_eq",
      "    (std:str:pad_start 5 \"∑∑∑\" \"∑∑\")",
      "    \"∑∑∑∑∑\";",
      "std:assert_eq",
      "    (std:str:pad_start 8 \"Ä∑ßs\" \"∑∑\")",
      "    \"ßsÄ∑ßs∑∑\";",
      "",
      "# Empty _pad-str_ is not an error but a nop:",
      "std:assert_eq",
      "    (std:str:pad_start 8 \"\" \"∑∑\")",
      "    \"∑∑\";",
      "",
      "# also works with characters",
      "std:assert_eq",
      "    (std:str:pad_start 3 'x' \"0\")",
      "    \"xx0\";",
      "# also works with bytes",
      "std:assert_eq",
      "    (std:str:pad_start 3 $b'x' \"0\")",
      "    \"xx0\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.15 - std:str:pad_end _len_ _pad-str_ _value_",
    [
      "",
      "Pads the stringified _value_ by _pad-str_ up to _len_ characters,",
      "appending at the end.",
      "The output string is guaranteed to be exactly _len_ unicode characters",
      "long and not longer. If _pad-str_ is empty, nothing is done.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:str:pad_end 2 \"Ä\" \"0\")",
      "    \"0Ä\";",
      "std:assert_eq",
      "    (std:str:pad_end 5 \"∑∑∑\" \"∑∑\")",
      "    \"∑∑∑∑∑\";",
      "std:assert_eq",
      "    (std:str:pad_end 8 \"Ä∑ßs\" \"∑∑\")",
      "    \"∑∑Ä∑ßsÄ∑\";",
      "",
      "# Empty _pad-str_ is not an error but a nop:",
      "std:assert_eq",
      "    (std:str:pad_end 8 \"\" \"∑∑\")",
      "    \"∑∑\";",
      "",
      "# also works with characters",
      "std:assert_eq",
      "    (std:str:pad_end 3 'x' \"0\")",
      "    \"0xx\";",
      "# also works with bytes",
      "std:assert_eq",
      "    (std:str:pad_end 3 $b'x' \"0\")",
      "    \"0xx\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.16 - std:str:to_bytes _string_",
    [
      "",
      "Encodes _string_ in UTF-8 and returns a byte vector containing all it's bytes.",
      "",
      "```wlambda",
      "!b = std:str:to_bytes \"1234\";",
      "std:assert_eq b $b\"1234\";",
      "",
      "!b = std:str:to_bytes \"Äß日本人\";",
      "std:assert_eq b $b\"\\xC3\\x84\\xC3\\x9F\\xE6\\x97\\xA5\\xE6\\x9C\\xAC\\xE4\\xBA\\xBA\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.17 - std:str:to_bytes_latin1 _string_",
    [
      "",
      "Encodes _string_ as bytes in Latin1 (ISO-8859-1) encoding and returns",
      "a byte vector containing all it's bytes. If a character is outside the Latin1 Unicode",
      "range, it will be replaced by a \"?\".",
      "",
      "```wlambda",
      "!b = std:str:to_bytes_latin1 \"\\u{FF}\\u{F0}\";",
      "std:assert_eq b $b\"\\xFF\\xF0\";",
      "!b = std:str:to_bytes_latin1 \"\\u{FE00}\\u{FF}\\u{3232}\";",
      "std:assert_eq b $b\"?\\xFF?\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.18 - std:str:from_latin1 _byte-vector_",
    [
      "",
      "Converts the _byte-vector_ to a Unicode string, assuming Latin 1 (ISO-8859-1) encoding",
      "and returns it.",
      "",
      "```wlambda",
      "!s = std:str:from_latin1 $b\"Ä\";",
      "std:assert_eq s \"\\u{C3}\\u{84}\";",
      "",
      "!s = std:str:from_latin1 $b\"\\xFF\\xF0\";",
      "std:assert_eq s \"\\u{FF}\\u{F0}\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.19 - std:str:from_utf8 _byte-vector_",
    [
      "",
      "Converts the _byte-vector_ to a Unicode string and returns it.",
      "If the _byte-vector_ contains invalid UTF-8 sequences an",
      "error value is returned.",
      "",
      "```wlambda",
      "!s = _? ~ std:str:from_utf8 $b\"\\xC3\\x84\\xC3\\x9F\\xE6\\x97\\xA5\\xE6\\x9C\\xAC\\xE4\\xBA\\xBA\";",
      "std:assert_eq s \"Äß日本人\";",
      "",
      "!r = on_error {|| _ } ~ std:str:from_utf8 $b\"\\xFF\\xFF\";",
      "std:assert_eq r \"str:from_utf8 decoding error: invalid utf-8 sequence of 1 bytes from index 0\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.20 - std:str:from_utf8_lossy _byte-vector_",
    [
      "",
      "Converts the _byte-vector_ to a Unicode string and returns it.",
      "If the _byte-vector_ contains invalid UTF-8 sequences a `\"�\"` will be",
      "inserted.",
      "",
      "```wlambda",
      "!s = _? ~ std:str:from_utf8_lossy",
      "    $b\"\\xC3\\x84\\xFF\\xC3\\x9F\\xE6\\x97\\xA5\\xE6\\x9C\\xAC\\xE4\\xBA\\xBA\\xFF\\xFF\\x00\";",
      "std:assert_eq s \"Ä�ß日本人��\\0\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.21 - std:str:to_char_vec _string_",
    [
      "",
      "Converts the _string_ into a vector of integers which represent the Unicode",
      "character number.",
      "",
      "```wlambda",
      "!v = std:str:to_char_vec \"1234\";",
      "std:assert_eq (str v) ~ str $[49,50,51,52];",
      "",
      "!v = std:str:to_char_vec \"Äß日本人\";",
      "std:assert_eq (str v) ~ str $[196,223,0x65E5,0x672C,0x4EBA];",
      "```",
      ""
    ]
  ],
  [
    "3.10.22 - std:str:from_char_vec _vector_",
    [
      "",
      "The reverse operation of `std:str:to_char_vec`. It converts",
      "a vector of integers to a unicode string. Any integer that has",
      "no associated Unicode character will be converted to `\"?\"`.",
      "",
      "```wlambda",
      "std:assert_eq (std:str:from_char_vec $[9999999999]) \"?\";",
      "std:assert_eq",
      "    (std:str:from_char_vec",
      "        $[49,50,196,223,0x65E5,0x672C,0x4EBA])",
      "    \"12Äß日本人\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.23 - std:str:to_lowercase _string_",
    [
      "",
      "Swaps all (Unicode) characters in _string_ to their lowercase version.",
      "",
      "```wlambda",
      "std:assert_eq (std:str:to_lowercase \"ZABzabÄßÜÖ\") \"zabzabäßüö\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.24 - std:str:to_uppercase _string_",
    [
      "",
      "Swaps all (Unicode) characters in _string_ to their lowercase version.",
      "",
      "```wlambda",
      "std:assert_eq (std:str:to_uppercase \"ZABzabäßüö\") \"ZABZABÄSSÜÖ\";",
      "```",
      ""
    ]
  ],
  [
    "3.10.25 - std:str:edit_distance _str-a_ _str_b",
    [
      "",
      "Calculates the Levenshtein distance between two (Unicode) strings.",
      "",
      "```wlambda",
      "std:assert_eq (std:str:edit_distance \"aaa\" \"aba\") 1;",
      "```",
      ""
    ]
  ],
  [
    "3.11 - Byte Vectors",
    [
      "",
      "Bytes (plural of Byte) are a vector of bytes. Unlike strings they don't have any encoding.",
      "Literal syntax however supports inserting unicode characters:",
      "",
      "",
      "```wlambda",
      "$b\"abc\";",
      "$b\"\\xFF\\xFD\\x00\";",
      "$Q/ABCDEF\\xFD/;      # \\xFD is not an escape sequence here!",
      "```",
      ""
    ]
  ],
  [
    "3.11.1 - Call Properties of Bytes",
    [
      "",
      "You can index inside a byte array by calling it with an integer:",
      "",
      "```wlambda",
      "std:assert_eq ($b\"ABC\" 1) $b'B';",
      "```",
      "",
      "You can extract a whole range when calling with 2 integers:",
      "",
      "```wlambda",
      "std:assert_eq ($b\"ABCDEF\" 2 3) $b\"CDE\";",
      "```",
      "",
      "If you call a bytes value with a map as argument, the bytes value is",
      "converted to a string internally using `str` and the value from the map",
      "is returned:",
      "",
      "```wlambda",
      "!some_map = ${ a = 20, b = 30 };",
      "",
      "std:assert_eq ($b\"a\" some_map) 20;",
      "std:assert_eq ($b\"b\" some_map) 30;",
      "",
      "std:assert_eq some_map.$b\"a\" 20;   # with method call syntax",
      "```",
      "",
      "If you call bytes with a pair as argument, you can do a multitude of",
      "operations, from replacement to finding a byte:",
      "",
      "```wlambda",
      "# replacing substrings:",
      "std:assert_eq ($b\"a,b,c,d\" $p($b',', $b';')) $b\"a;b;c;d\";",
      "std:assert_eq ($b\"a,b,c,d\" $p($b\"a,\", $b\"XXX\")) $b\"XXXb,c,d\";",
      "# also works with strings and chars:",
      "std:assert_eq ($b\"a,b,c,d\" $p(\"a,\", \"XXX\")) $b\"XXXb,c,d\";",
      "std:assert_eq ($b\"a,b,c,d\" $p(\"a,\", 'O')) $b\"Ob,c,d\";",
      "",
      "# finding a character/byte:",
      "std:assert_eq ($b\"a,b,c,d\" $p(0, $b'c')) 4;",
      "std:assert_eq ($b\"a,b,c,d\" $p(0,   'c')) 4;",
      "",
      "# splitting:",
      "std:assert_str_eq ($b\"A\\<SOH>B\\<SOH>C\" $p($b'\\<SOH>', 0)) $[$b\"A\", $b\"B\", $b\"C\"];",
      "```",
      "",
      "See also the section [Calling Semantics of Data Types](#319-calling-semantics-of-data-types).",
      ""
    ]
  ],
  [
    "3.11.2 - Byte Conversion Functions",
    [
      "",
      "You can convert bytes to strings in a multitude of ways:",
      "",
      "- str _bytes_",
      "  ```wlambda",
      "  std:assert_eq (str $b\"abc\")        \"abc\";",
      "  std:assert_eq (str $b\"abc\\xFF\")    \"abcÿ\";",
      "  std:assert_eq (str $Q/ABCDEF\\xFD/) \"ABCDEF\\\\xFD\";",
      "  ```",
      "- std:bytes:to\\_hex _bytes_ \\[_group-len_ \\[_group-sep_]]",
      "  ```wlambda",
      "  std:assert_eq (std:bytes:to_hex $b\"\\xFF\\x0A\\xBE\\xEF\")",
      "                \"FF0ABEEF\";",
      "  std:assert_eq (std:bytes:to_hex $b\"\\xFF\\x0A\\xBE\\xEF\" 2)",
      "                \"FF 0A BE EF\";",
      "  std:assert_eq (std:bytes:to_hex $b\"\\xFF\\x0A\\xBE\\xEF\" 2 \":\")",
      "                \"FF:0A:BE:EF\";",
      "  ```",
      "- std:str:from\\_latin1 _bytes_",
      "  ```wlambda",
      "  std:assert_eq (std:str:from_latin1 $b\"\\xFF\\xF0\") \"\\u{FF}\\u{F0}\";",
      "  ```",
      "- std:str:from\\_utf8 _bytes_",
      "  ```wlambda",
      "  std:assert_eq (std:str:from_utf8 $b\"\\xC3\\xA4\\xC3\\x9F\\xC3\\xBF\") \"äßÿ\";",
      "  std:assert_eq (std:str:from_utf8 [std:str:to_bytes \"äßÿ\"])         \"äßÿ\";",
      "  # broken UTF8 will result in an error:",
      "  std:assert ~ is_err (std:str:from_utf8 $b\"\\xC3\\xC3\\xA4\\xC3\\x9F\\xC3\\xBF\");",
      "  ```",
      "- std:str:from\\_utf8\\_lossy _bytes_",
      "  ```wlambda",
      "  std:assert_eq (std:str:from_utf8_lossy $b\"\\xC3\\xC3\\xA4\\xC3\\x9F\\xC3\\xBF\") \"�äßÿ\";",
      "  ```",
      "",
      "You can even convert bytes to vectors of integers back and forth:",
      "",
      "```wlambda",
      "!v = std:bytes:to_vec $b\"ABC\";",
      "std:assert_eq (str v) (str $[65, 66, 67]);",
      "",
      "std:push v 64;",
      "!b = std:bytes:from_vec v;",
      "std:assert_eq b $b\"ABC@\";",
      "```",
      "",
      "There is also an inverse operation to `bytes:to_hex`:",
      "",
      "```wlambda",
      "std:assert_eq (std:bytes:from_hex ~ std:bytes:to_hex $b\"ABC\") $b\"ABC\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.3 - is_bytes _value_",
    [
      "",
      "Returns `$true` if _value_ is a byte vector.",
      "",
      "```wlambda",
      "std:assert ~ is_bytes $b\"ABC\";",
      "std:assert ~ not ~ is_bytes \"ABC\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.4 - std:bytes:find _pattern_ _string_ [_offset_]",
    [
      "",
      "Searches for the string _pattern_ in the _string_ and returns the 0 based position",
      "in the string the given _pattern_ starts.",
      "If no pattern was found `$none` is returned.",
      "",
      "```wlambda",
      "std:assert_eq (std:bytes:find $b\"xyz\" $b\"abcxyz\")         3;",
      "std:assert_eq (std:bytes:find $b\"xyz\" $b\"abcxyzxyz\" 6)    6;",
      "std:assert_eq (std:bytes:find $b\"xyz\" $b\"abcxyzfooxyz\" 6) 9;",
      "```",
      ""
    ]
  ],
  [
    "3.11.5 - std:bytes:replace _byte-vector_ _pattern_ _replacement_",
    [
      "",
      "Replaces all occurences of _pattern_ in _byte-vector_ with _replacement_.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:replace $b\"XXX\\x01\\x02\\x03OOO\" $b\"\\x01\\x02\\x03\" $b\"---\")",
      "    $b\"XXX---OOO\";",
      "",
      "std:assert_eq",
      "    (std:bytes:replace $b\"XXX\\x01\\x02\\x03OOO\" $b\"\\x01\\x02\\x03\" $b\"\")",
      "    $b\"XXXOOO\";",
      "",
      "std:assert_eq",
      "    (std:bytes:replace $b\"XXX\\x01\\x02\\x03OOO\" $b\"\\x01\\x02\\x03\" $b\"\\xFF\\xFF\\xFF\\xFF\")",
      "    $b\"XXX\\xFF\\xFF\\xFF\\xFFOOO\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.6 - std:bytes:from_hex _string-with-hex-chars_",
    [
      "",
      "This function decodes a string of hex characters into a byte vector.",
      "",
      "```wlambda",
      "!bv = std:bytes:from_hex \"62797465\";",
      "std:assert_eq bv $b\"byte\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.7 - std:bytes:from_vec _vector-of-ints_",
    [
      "",
      "Decodes a vector of integers in the range 0-255 into a byte vector. If an",
      "integer is larger than 255 don't expect a sensible result. But it will most",
      "likely just wrap around.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:from_vec $[1,2,3,0x62,0x79,0x74,0x65])",
      "    $b\"\\x01\\x02\\x03byte\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.8 - std:bytes:to_hex _byte-vector_",
    [
      "",
      "Converts the given byte vector to a string of hex encoded bytes.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:to_hex $b\"byte\")",
      "    \"62797465\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.9 - std:bytes:to_base64 _byte-vector_ [_config_]",
    [
      "",
      "Converts the given byte vector to a Base64 encoded string. With _config_ you can",
      "define the encoding style:",
      "",
      "- `:std`",
      "- `:std_no_pad`",
      "- `:url`",
      "- `:url_no_pad`",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:to_base64 $b\"\\x00\\xFF\")",
      "    \"AP8=\";",
      "std:assert_eq",
      "    (std:bytes:to_base64 \"test\")",
      "    \"dGVzdA==\";",
      "std:assert_eq",
      "    (std:bytes:to_base64 \"test\" :std_no_pad)",
      "    \"dGVzdA\";",
      "std:assert_eq",
      "    (std:bytes:from_base64 (std:bytes:to_base64 \"test\"))",
      "    $b\"test\";",
      "std:assert_eq",
      "    (std:bytes:from_base64 (std:bytes:to_base64 \"test\" :url) :url)",
      "    $b\"test\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.10 - std:bytes:from_base64 _byte-vector_ [_config_]",
    [
      "",
      "Converts the given byte vector to a Base64 encoded string. With _config_ you can",
      "define the encoding style, see also `to_base64` for a list of possible values.",
      "",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:from_base64 \"AP8=\")",
      "    $b\"\\x00\\xFF\";",
      "std:assert_eq",
      "    (std:bytes:from_base64 \"dGVzdA\")",
      "    $b\"test\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.11 - std:bytes:to_vec _byte-vector_",
    [
      "",
      "Converts the given byte vector to a vector of integers in the range 0-255.",
      "",
      "```wlambda",
      "std:assert_str_eq",
      "    (std:bytes:to_vec $b\"byte\")",
      "    $[98, 121, 116, 101];",
      "```",
      ""
    ]
  ],
  [
    "3.11.12 - std:bytes:pack _pack-format-string_ _list-of-values_",
    [
      "",
      "Returns a byte vector containing the values of _list-of-values_",
      "serialized in binary form (packed) according to the given _pack-format-string_.",
      "",
      "If the syntax of the _pack-format-string_ has errors, an error value is returned.",
      "",
      "See also the section [Format String Syntax](#133-format-string-syntax-for-stdbytespack-and-stdbytesunpack)",
      "for a description of the syntax for _pack-format-string_.",
      "",
      "This function is very useful for constructing binary data for file formats and",
      "network protocols.",
      "",
      "```wlambda",
      "std:assert_eq",
      "    (std:bytes:pack \"> i16 x s8 x f\" $[1, \"test\", 0.5])",
      "    $b\"\\0\\x01\\0\\x04test\\0?\\0\\0\\0\";",
      "```",
      ""
    ]
  ],
  [
    "3.11.13 - std:bytes:unpack _pack-format-string_ _byte-vector_",
    [
      "",
      "Decodes the given _byte-vector_ according to the _pack-format-string_ and returns it",
      "as list of values.",
      "",
      "If the syntax of the _pack-format-string_ has errors or the given _byte-vector_",
      "is too short, an error value is returned.",
      "",
      "See also the section [Format String Syntax](#133-format-string-syntax-for-stdbytespack-and-stdbytesunpack)",
      "for a description of the syntax for _pack-format-string_.",
      "",
      "```wlambda",
      "std:assert_str_eq",
      "    (std:bytes:unpack",
      "        \"< i16 x c3 s16 x y\"",
      "        $b\"\\x10\\x00\\x00ABC\\x02\\x00XY\\x00This is the rest\")",
      "    $[16, $b\"ABC\", $b\"XY\", $b\"This is the rest\"];",
      "```",
      ""
    ]
  ],
  [
    "3.12 - Symbols",
    [
      "",
      "Symbols are a special kind of strings that are interned by the runtime.  That",
      "means, comparing two symbols is an O(1) operation and not an O(n) operation on",
      "the length of the string. Symbols are also used as keys for maps.  Use them",
      "however you see fit. They will do a key lookup (on maps, vectors (as indices)",
      "and user values) if they are called with an argument.",
      "",
      "```wlambda",
      "std:assert_eq (:1 $[1,2,3]) 2;",
      "std:assert_eq (:a ${a=30}) 30;",
      "```",
      "",
      "They are basically the same as string, but strings have",
      "slightly different calling semantics and a different literal syntax.",
      "Often you can use them as shortform literal in places where a string",
      "is expected:",
      "",
      "```wlambda",
      "std:assert_eq (std:str:replace :A :a \"All AbabA\") \"all ababa\";",
      "```",
      "",
      "They can be very useful as sentinel values or custom enums:",
      "",
      "```wlambda",
      "!x = :ON;",
      "!y = :OFF;",
      "",
      "std:assert_eq ((x == :ON) { 10 }) 10;",
      "",
      "# They don't match with strings:",
      "std:assert_eq ((x == \"ON\") { 10 } { 20 }) 20;",
      "",
      "# Work together nicely with `match`:",
      "",
      "!state = \"\";",
      "match x",
      "    :ON  => { .state = \"is on\" }",
      "    :OFF => { .state = \"is off\" };",
      "std:assert_eq state \"is on\";",
      "",
      "match y",
      "    :ON  => { .state = \"is on\" }",
      "    :OFF => { .state = \"is off\" };",
      "std:assert_eq state \"is off\";",
      "```",
      "",
      "Keep in mind, that all symbols are interned strings. And if you create many",
      "symbols that are not used anymore, you might need to trigger a cleanup",
      "with `std:symbols::collect`.",
      "",
      "The collection of dead symbols is also run automatically for every 100th newly",
      "allocated symbol.",
      ""
    ]
  ],
  [
    "3.12.1 - sym _value_",
    [
      "",
      "Casts the given _value_ into a symbol.",
      "",
      "```wlambda",
      "std:assert_eq (sym \"a\")     :a;",
      "std:assert_eq (sym $b\"a\")   :a;",
      "std:assert_eq (sym $[])     :\"$[]\";",
      "std:assert_eq (sym 10)      :10;",
      "```",
      ""
    ]
  ],
  [
    "3.12.2 - is_sym _value_",
    [
      "",
      "Returns `$true` if the _value_ is symbol.",
      "",
      "```wlambda",
      "std:assert ~ is_sym :a;",
      "std:assert ~ is_sym ~ sym \"a\";",
      "std:assert ~ is_sym ~ sym \"a\";",
      "std:assert ~ is_sym ~ sym $b\"a\";",
      "",
      "std:assert ~ not ~ is_sym \"a\";",
      "std:assert ~ not ~ is_sym $b\"a\";",
      "std:assert ~ not ~ is_sym $&&:a;",
      "std:assert ~ not ~ is_sym ${};",
      "std:assert ~ not ~ is_sym $none;",
      "std:assert ~ not ~ is_sym $true;",
      "```",
      ""
    ]
  ],
  [
    "3.12.3 - std:symbols:collect",
    [
      "",
      "Collect and remove all interned symbols in the current thread that are no",
      "longer used. Returns the number of freed symbols. Please keep in mind, that",
      "the `std:ref_id` of any collected symbol will be different from a symbol that",
      "is created later with the same characters.",
      "",
      "The collection of dead symbols is also run automatically for every 100th newly",
      "allocated symbol.",
      "",
      "If you rely on the reference ID of a symbol, you should make sure to keep it",
      "around. Literal symbols are always kept around as long as the code is running",
      "or referenced somewhere (eg. by a function).",
      "",
      "",
      "```wlambda",
      "std:symbols:collect[];",
      "",
      "!probably_unique_sym = sym \"onceonly_used\";",
      "",
      "std:assert_eq",
      "    (std:ref_id ~ sym \"onceonly_used\")",
      "    (std:ref_id probably_unique_sym);",
      "",
      "std:assert_eq std:symbols:collect[] 0;",
      "",
      ".probably_unique_sym = $none;",
      "",
      "std:assert_eq std:symbols:collect[] 1;",
      "```",
      ""
    ]
  ],
  [
    "3.13 - Syntax `$%:Block`",
    [
      "",
      "A syntax element is an element of an abstract syntax tree as it is returned",
      "by `std:wlambda:parse` for instance. They carry the type of syntax node",
      "and debug information with them.",
      ""
    ]
  ],
  [
    "3.13.1 - std:syn:pos _syntax_",
    [
      "",
      "Returns the position of the syntax element in the source code.",
      "",
      "```wlambda",
      "!ast = std:wlambda:parse \"1 + 2\";",
      "!add_syntax = ast.1.0;",
      "",
      "std:assert_str_eq",
      "    (std:syn:pos add_syntax)",
      "    $[\"<wlambda:parse:input>\", 1, 3];",
      "```",
      ""
    ]
  ],
  [
    "3.13.2 - std:syn:type _syntax_",
    [
      "",
      "Converts the syntax element to a symbol, so you can determine it's type:",
      "",
      "```wlambda",
      "!ast = std:wlambda:parse \"1 + 2\";",
      "!add_syntax = ast.1.0;",
      "",
      "std:assert_str_eq",
      "    (std:syn:type add_syntax)",
      "    :BinOpAdd;",
      "```",
      ""
    ]
  ],
  [
    "3.14 - Pairs `$p(a, b)`",
    [
      "",
      "A pair is an immutable tuple of 2 values. You can use it for returning two",
      "values from a function as it is a slight bit slimmer than a vector with two",
      "values. Unlike a vector, pairs are compared by `==` according to their contents",
      "and not by referencial equality.",
      "",
      "There are two ways to form a pair:",
      "",
      "- Pair value syntax: `$p(a, b)`",
      "- Pair right associative operator: `a => b`",
      "",
      "You can access the pair values by the following keys:",
      "",
      "```wlambda",
      "!v = $p(11, 12);",
      "",
      "std:assert_eq v.0     11;",
      "std:assert_eq v.1     12;",
      "std:assert_eq (0 v)   11;",
      "std:assert_eq (1 v)   12;",
      "",
      "std:assert_eq v.car   11;",
      "std:assert_eq v.cdr   12;",
      "",
      "std:assert_eq v.head  11;",
      "std:assert_eq v.tail  12;",
      "",
      "std:assert_eq v.first    11;",
      "std:assert_eq v.second   12;",
      "",
      "# Pairs are often used to represent map entries,",
      "# so you can use `key` and `value`",
      "# and the short forms `k` and `v` too:",
      "std:assert_eq v.value 11;",
      "std:assert_eq v.key   12;",
      "",
      "std:assert_eq v.v     11;",
      "std:assert_eq v.k     12;",
      "```",
      "",
      "Comparison does happen by their contents:",
      "",
      "```wlambda",
      "std:assert $p(1, 2) == $p(1, 2);",
      "std:assert $p(2, 2) != $p(1, 2);",
      "",
      "# In contrast to vectors:",
      "std:assert not ~ $[1, 2] == $[1, 2];",
      "```",
      "",
      "The index is wrapping around, that means `$p(a, b).2` is the first element again:",
      "",
      "```wlambda",
      "!v = $p(33, 44);",
      "!l = $[];",
      "",
      "iter i $i(0, 4)",
      "    ~ std:push l v.(i);",
      "",
      "std:assert_eq (str l) (str $[33, 44, 33, 44]);",
      "```",
      "",
      "A pair is a referencial data type, that means you can use `std:ref_id` on it:",
      "",
      "```wlambda",
      "!a = $p(1, 2);",
      "!b = $p(2, 3);",
      "!id_a = std:ref_id a;",
      "!id_b = std:ref_id b;",
      "",
      "std:assert (id_a != id_b);",
      "std:assert std:ref_id[a] == id_a;",
      "",
      "!v = $[a];",
      "std:assert std:ref_id[v.0] == id_a;",
      "```",
      ""
    ]
  ],
  [
    "3.14.1 - Pair Operator `a => b`",
    [
      "",
      "Writing `a => b` operator is the same as writing `$p(a, b)`.  However, the",
      "precedence of the `=>` operator is the lowest and right associative, so writing",
      "this is possible:",
      "",
      "```wlambda",
      "!p = 1 + 2 => 3 + 4;",
      "",
      "std:assert_eq p $p(3, 7);",
      "```",
      "",
      "The following example shows off the associativity of the operator:",
      "",
      "```wlambda",
      "!a = 1 => 2;",
      "!b = 2 => 3 => 4;",
      "",
      "std:assert_eq a $p(1, 2);",
      "std:assert_eq b $p(2, $p(3, 4));",
      "std:assert_eq b 2 => 3 => 4;",
      "```",
      ""
    ]
  ],
  [
    "3.14.2 - cons _a_ _b_",
    [
      "",
      "Creates a new pair from the values _a_ and _b_.",
      "",
      "```wlambda",
      "!p = cons 3 4;",
      "",
      "std:assert_eq p $p(3, 4);",
      "```",
      ""
    ]
  ],
  [
    "3.14.3 - Pair string/byte vector operations",
    [
      "",
      "If you call a pair with a string or byte vector as argument, there are some",
      "operations that can be done:",
      ""
    ]
  ],
  [
    "3.14.3.1 - $p( _from_ , _count_ ) _string-or-byte-vec_",
    [
      "",
      "Returns a substring starting at _from_ with the length _count_.",
      "",
      "```wlambda",
      "std:assert_eq ($p(2, 4) \"abcdefgh\") \"cdef\";",
      "```",
      "",
      "The same works for byte vectors:",
      "",
      "```wlambda",
      "std:assert_eq ($p(2, 4) $b\"abcdefgh\") $b\"cdef\";",
      "```",
      ""
    ]
  ],
  [
    "3.14.3.2 - $p( _pattern_ , _replacement_ ) _string-or-byte-vec_",
    [
      "",
      "Replaces all _pattern_ occurences in _string_ by _replacement_.",
      "",
      "```wlambda",
      "std:assert_eq ($p(\";\", \"_\") \"A;B;D;EFG;HI\") \"A_B_D_EFG_HI\";",
      "```",
      "",
      "The same works for byte vectors:",
      "",
      "```wlambda",
      "std:assert_eq ($p($b\";\", $b\"_\") $b\"A;B;D;EFG;HI\") $b\"A_B_D_EFG_HI\";",
      "```",
      ""
    ]
  ],
  [
    "3.14.3.3 - $p( _split-pattern_ , _max_ ) _string-or-byte-vec_",
    [
      "",
      "Splits _string_ at _split-pattern_ a _max_ number of times.",
      "If _max_ is 0, it is split completely.",
      "",
      "```wlambda",
      "std:assert_eq str[$p(\";\", 3) \"A;B;D;EFG;HI\"] ~ str $[\"A\", \"B\", \"D;EFG;HI\"];",
      "",
      "std:assert_eq str[$p(\";\", 0) \"A;B;D;EFG;HI\"] ~ str $[\"A\", \"B\", \"D\", \"EFG\", \"HI\"];",
      "```",
      "",
      "The same works for byte vectors:",
      "",
      "```wlambda",
      "std:assert_eq str[$p($b\";\", 0) $b\"A;B;D;EFG;HI\"] ~ str $[$b\"A\", $b\"B\", $b\"D\", $b\"EFG\", $b\"HI\"];",
      "```",
      ""
    ]
  ],
  [
    "3.14.4 - Pair to Iterator",
    [
      "",
      "Pairs play a special role if you make an iterator from it.",
      "It can be used to create a specialized iterator that only",
      "iterates over keys or values of a map. Or that enumerates",
      "a vector or map.",
      ""
    ]
  ],
  [
    "3.14.4.1 - Iter - Range",
    [
      "",
      "`$iter $p(0, 10)` is the same as `$iter $i(0, 10)` and will construct an",
      "iterator that iterates from `0` to `9` (inclusive).",
      "Because of the pair operator `a => b` we can nicely write a counting loop like this:",
      "",
      "```wlambda",
      "!sum = $@i",
      "    iter i 0 => 10 {",
      "        $+ i;",
      "    };",
      "std:assert_eq sum 45;",
      "```",
      ""
    ]
  ],
  [
    "3.14.4.2 - Iter - Enumerate",
    [
      "",
      "If the first value of the pair is `:enumerate`",
      "it will enumerate entries in a map or values in a vector.",
      "",
      "```wlambda",
      "!v = $[];",
      "",
      "# $iter is only explicit here for demonstration",
      "# purposes! `iter` will make an iter from the pair",
      "# if you don't pass one!",
      "iter i ($iter $p(:enumerate, $[:a, :b, :c]))",
      "    ~ std:push v i;",
      "",
      "std:assert_eq (str v) (str $[0, 1, 2]);",
      "```",
      "",
      "For maps:",
      "",
      "```wlambda",
      "!v = $[];",
      "iter i $p(:enumerate, ${a = 10, b = 20})",
      "    ~ std:push v i;",
      "",
      "std:assert_eq (str v) (str $[0, 1]);",
      "```",
      ""
    ]
  ],
  [
    "3.14.4.3 - Iter - Values",
    [
      "",
      "This is useful for iterating over the values in a map in an undefined order:",
      "",
      "```wlambda",
      "!m = ${ a = 10, b = 20, c = 33 };",
      "",
      "!sum = $@i iter v $p(:values, m) ~ $+ v;",
      "",
      "std:assert_eq sum 63;",
      "```",
      ""
    ]
  ],
  [
    "3.14.4.4 - Iter - Keys",
    [
      "",
      "You can also iterate over map keys in an undefined order:",
      "",
      "```wlambda",
      "!m = ${ :10 = :c, :20 = :b, :30 = :a };",
      "",
      "!sum = $@i iter v $p(:keys, m) ~ $+ v;",
      "",
      "std:assert_eq sum 60;",
      "```",
      ""
    ]
  ],
  [
    "3.14.5 - is_pair _value_",
    [
      "",
      "Checks if _value_ is a pair.",
      "",
      "```wlambda",
      "std:assert ~ is_pair $p(1, 2);",
      "std:assert not ~ is_pair $[1, 2];",
      "std:assert not ~ is_pair $i(1, 2);",
      "```",
      ""
    ]
  ],
  [
    "3.15 - Vectors (or Lists)",
    [
      "",
      "The literal syntax for vectors (or sometimes also called lists in WLambda)",
      "is `$[...]`. You may write any kind of expression in it and you will get",
      "a vector from it.",
      "",
      "For iteration over a vector please refer to [5.2 Collection Iteration](#52-collection-iteration).",
      "",
      "To access the elements of a vector you have to call a number with a vector",
      "as first argument. The field syntax is a more convenient shorthand syntax.",
      "The following example demonstrates it:",
      "",
      "```wlambda",
      "!add20 = { _ + 20 };",
      "",
      "!some_vec = $[1, 2 * 10, add20 10]; ",
      "",
      "# Index calling:",
      "std:assert_eq (0 some_vec) 1;",
      "std:assert_eq (1 some_vec) 20;",
      "std:assert_eq (2 some_vec) 30;",
      "",
      "# Field syntax:",
      "std:assert_eq some_vec.0 1;",
      "std:assert_eq some_vec.1 20;",
      "std:assert_eq some_vec.2 30;",
      "```",
      "",
      "To add elements to a vector, you can use the prepend and append operators `+>`",
      "and `<+` too:",
      "",
      "```wlambda",
      "!v = $[1];",
      "",
      "0 <+ v;",
      "v +> 2;",
      "",
      "std:assert_str_eq v $[0,1,2];",
      "```",
      ""
    ]
  ],
  [
    "3.15.1 - std:push _vector_ _item_",
    [
      "",
      "Pushes _item_ to the end of _vector_. Returns _item_.",
      "Be aware, that there is also the `+>` operator, that will append elements",
      "to a vector.",
      "",
      "```wlambda",
      "!v = $[1,2];",
      "",
      "std:push v 3;",
      "",
      "std:assert_eq (str v) (str $[1,2,3]);",
      "```",
      ""
    ]
  ],
  [
    "3.15.2 - std:pop _vector_",
    [
      "",
      "Pops off the last element of _vector_. Returns `$none` if the vector is empty",
      "or if _vector_ is not a vector.",
      "",
      "```wlambda",
      "!v = $[1,2,3];",
      "",
      "std:assert_eq (std:pop v) 3;",
      "std:assert_eq (str v) (str $[1,2]);",
      "```",
      ""
    ]
  ],
  [
    "3.15.3 - std:unshift _vector_ _item_",
    [
      "",
      "Inserts _item_ at the front of _vector_. Returns _item_ and mutates _vector_",
      "inplace. Be aware that this operation is of O(n) complexity.",
      "Be aware, that there is also the `<+` operator, that will prepend elements",
      "to a vector (with O(n) complexity however).",
      "",
      "```wlambda",
      "!v = $[1,2];",
      "",
      "std:unshift v 3;",
      "",
      "std:assert_eq (str v) (str $[3,1,2]);",
      "```",
      ""
    ]
  ],
  [
    "3.15.4 - is_vec _value_",
    [
      "",
      "Returns `$true` if _value_ is a vector.",
      "",
      "```wlambda",
      "std:assert ~ is_vec $[];",
      "std:assert ~ is_vec $[1,2,3];",
      "",
      "std:assert ~ not ~ is_vec 0;",
      "std:assert ~ not ~ is_vec $none;",
      "std:assert ~ not ~ is_vec $true;",
      "std:assert ~ not ~ is_vec $p(1,2);",
      "std:assert ~ not ~ is_vec $i(1,2);",
      "std:assert ~ not ~ is_vec $f(1,2);",
      "std:assert ~ not ~ is_vec ${a = 10};",
      "```",
      ""
    ]
  ],
  [
    "3.15.5 - Vector Splicing",
    [
      "",
      "You can splice vectors directly into their literal form with the `$[..., * vec_expr, ...]`",
      "syntax. Here is an example:",
      "",
      "```wlambda",
      "!make_some = { $[_ + 1, _ + 2] };",
      "",
      "!some_vec = $[ 0, *make_some 1 ];",
      "",
      "std:assert_eq some_vec.1 2;",
      "std:assert_eq some_vec.2 3;",
      "",
      "# There can be any expression after the `.` if you wrap it into `(...)`:",
      "std:assert_eq some_vec.(1 + 1) 3;",
      "",
      "# A more direct example:",
      "std:assert_eq (str $[1,2,*$[3,4]]) \"$[1,2,3,4]\";",
      "```",
      ""
    ]
  ],
  [
    "3.15.6 - std:append _vec-a_ _value-or-vec_ ...",
    [
      "",
      "Appends _value-or-vec_ and all following items to _vec-a_.",
      "If _value-or-vec_ is a vector, all its items will be appended to _vec-a_.",
      "",
      "```wlambda",
      "!v = std:append $[1,2,3] :a :b $[:c, :d];",
      "",
      "std:assert_eq (str v) \"$[1,2,3,:a,:b,:c,:d]\";",
      "```",
      "",
      "If _vec-a_ is not a vector, a vector containing it will be created:",
      "",
      "```wlambda",
      "!v = std:append 1 :a :b $[:c, :d];",
      "",
      "std:assert_eq (str v) \"$[1,:a,:b,:c,:d]\";",
      "```",
      ""
    ]
  ],
  [
    "3.15.7 - std:prepend _vec-a_ _value-or-vec_ ...",
    [
      "",
      "Prepends _value-or-vec_ and all following items to the front of _vec-a_.",
      "If _value-or-vec_ is a vector, all its items will be prepended to _vec-a_.",
      "",
      "```wlambda",
      "!v = std:prepend $[1,2,3] :a :b $[:c, :d];",
      "",
      "std:assert_eq (str v) (str $[:d, :c, :b, :a, 1, 2, 3]);",
      "```",
      "",
      "If _vec-a_ is not a vector, a vector containing it will be created:",
      "",
      "```wlambda",
      "!v = std:prepend 1 :a :b $[:c, :d];",
      "",
      "std:assert_eq (str v) (str $[:d, :c, :b, :a, 1]);",
      "```",
      ""
    ]
  ],
  [
    "3.15.8 - std:take _count_ _vector_",
    [
      "",
      "Takes and returns the first _count_ elements of _vector_. Does not",
      "mutate _vector_.",
      "",
      "```wlambda",
      "!v = $[1,2,3,4,5,6];",
      "",
      "!t = std:take 4 v;",
      "",
      "std:assert_eq (str v) \"$[1,2,3,4,5,6]\";",
      "std:assert_eq (str t) \"$[1,2,3,4]\";",
      "```",
      ""
    ]
  ],
  [
    "3.15.9 - std:drop _count_ _vector_",
    [
      "",
      "Drops _count_ elements from _vector_ and returns them as new vector.",
      "Does not mutate _vector_.",
      "",
      "```wlambda",
      "!v = $[1,2,3,4,5,6];",
      "",
      "!t = std:drop 4 v;",
      "",
      "std:assert_eq (str v) \"$[1,2,3,4,5,6]\";",
      "std:assert_eq (str t) \"$[5,6]\";",
      "```",
      ""
    ]
  ],
  [
    "3.16 - Associative Maps (or String to Value mappings)",
    [
      "",
      "Aside from vectors there are associative maps in WLambda. Their syntax is",
      "`${ key = expr, ... }`. The keys of these maps have to be symbols (or strings),",
      "the values in the literals can be any expression. Keys for maps are interned strings,",
      "so keep that in mind if you fill a map with garbage keys.",
      "",
      "For iteration over a map please refer to [5.2 Collection Iteration](#52-collection-iteration).",
      "",
      "You can call a symbol or a string with an associative map to get the value in",
      "the map with the string value as key. There is also, like vectors, the field",
      "calling syntax. Here are some examples:",
      "",
      "```wlambda",
      "!some_map = ${ a = 1, b = 2 };",
      "",
      "# Symbol calling:",
      "std:assert_eq (:a some_map) 1;",
      "std:assert_eq (:b some_map) 2;",
      "std:assert_eq (\"a\" some_map) 1;",
      "std:assert_eq (\"b\" some_map) 2;",
      "",
      "# Field syntax:",
      "std:assert_eq some_map.a 1;",
      "std:assert_eq some_map.b 2;",
      "",
      "# There can be any expression after the `.` if you wrap it into `(...)`,",
      "# also strings:",
      "std:assert_eq some_map.(\"a\") 1;",
      "std:assert_eq some_map.(\"b\") 2;",
      "```",
      "",
      "Keys can also be computed at runtime in the literal form:",
      "",
      "```wlambda",
      "!some_map = ${ (std:str:cat \"a\" \"b\") = 10 };",
      "",
      "std:assert_eq (str some_map) \"${ab=10}\";",
      "```",
      "",
      "If you call a field that is being accessed directly using",
      "the field accessing syntax `some_map.a`, the function is passed the map `some_map`",
      "via the special value `$self`. There is another special variable `$data`",
      "that allows you to access the `$self._data` field.",
      ""
    ]
  ],
  [
    "3.16.1 - Map Splicing",
    [
      "",
      "Like vectors you can splice map values directly into map literals:",
      "",
      "```wlambda",
      "!map_gen = { ${ (std:str:cat \"_\" _) = _ } };",
      "",
      "!some_map = ${ a = 10, *map_gen \"x\" };",
      "",
      "std:assert_eq some_map.a 10;",
      "std:assert_eq some_map._x \"x\";",
      "",
      "std:assert_eq (str ${*${a=10}}) \"${a=10}\";",
      "",
      "# As a reminder, a full expression can come after the '*':",
      "",
      "std:assert_eq (str ${*map_gen \"y\"}) $q/${_y=\"y\"}/;",
      "```",
      ""
    ]
  ],
  [
    "3.16.2 - is_map _value_",
    [
      "",
      "Returns `$true` if _value_ is a map.",
      "",
      "```wlambda",
      "std:assert ~ is_map ${};",
      "std:assert ~ is_map ${a = 10};",
      "",
      "std:assert ~ not ~ is_map $&&${};",
      "std:assert ~ not ~ is_map $&${};",
      "std:assert ~ not ~ is_map $[:a, 10];",
      "std:assert ~ not ~ is_map $p(:a, 10);",
      "std:assert ~ not ~ is_map $none;",
      "std:assert ~ not ~ is_map $true;",
      "```",
      ""
    ]
  ],
  [
    "3.17 - References",
    [
      "",
      "TODO",
      "    - 3 types: strong, hidden, weak",
      "        - strong:",
      "            - `$&&`",
      "            - mention DWIM'ery",
      "        - hidden:",
      "            - `$&`",
      "            - mention usage for closures",
      "            - how to \"Unhide\" a reference using `$:`",
      "        - weak:",
      "            - std:ref:weaken and `$w&`",
      "            - how to break reference cycles",
      "            - how weak references are also caught weakly",
      "              by closures and not strongly.",
      "            - how to get a strong reference using `$:`",
      "",
      "Some data structures already have reference characteristics, such as strings,",
      "vectors and maps. But you can also wrap other values like integers, floats, ...",
      "into a reference. There are 3 types of references in WLambda that have",
      "different usecases and semantics. These referential types are neccessary to",
      "mutate lexical variables from a parent scope. To give a rather natural example:",
      "",
      "```wlambda",
      "!x = 10;",
      "{ .x = 20; }[];",
      "std:assert_eq x 20;",
      "```",
      "",
      "The example works rather intuitively. There is however lots of implicit",
      "referential stuff going on. Once `x` is captured by a closure its contents is implicitly",
      "changed in to a _hidden_ `$&` reference. The closure then stores this hidden",
      "reference too. You have to be aware of this, because in some use cases this can lead",
      "to cyclic reference structures, which are not automatically freed. Please use",
      "weak references `$w&` for mitigating this.",
      "",
      "Hidden references and weak references captured by a closure are dereferenced",
      "implicitly if you access the variables. Weak references in the local scope are",
      "not implicitly dereferenced. However, sometimes it's desirable to have a more",
      "explicit reference data types. For this the strong references `$&&` are",
      "available. Use `$*` for accessing the value of a strong reference or a weak reference",
      "in the local scope.",
      "",
      "TODO",
      "",
      "These types of references exist:",
      "",
      "- `$&` - A _hidden_ reference, that is captured by closures or constructed using `$&`.",
      "- `$w&` - A _weak_ reference, can't be constructed literally, only indirectly",
      "as upvalue of a closure or by `std:ref:weaken`.",
      "- `$&&` - A _strong_ reference, that is captured strongly by closures.",
      "Inside closures they are also implicitly dereferenced by assignment",
      "and access by variable name.",
      "",
      "```wlambda",
      "!x = $& 10;",
      "",
      "{ .x = 20; }[]; # Closures implicitly handle weak references",
      "",
      "std:assert_eq x 20;",
      "```",
      "",
      "And the same with strong references:",
      "",
      "```wlambda",
      "!x = $&& 10;",
      "",
      ".*x = 11;",
      "",
      "{ .*x = 20; }[]; # Closures need explicit handling of strong references",
      "",
      "std:assert_eq $*x 20;",
      "```",
      "",
      "Strong references can also be created using the `std:to_ref` function and",
      "the `$:` operation.",
      ""
    ]
  ],
  [
    "3.17.1 - std:to_ref _value_",
    [
      "",
      "Creates a new strong reference that refers to a cell that stores _value_.",
      "",
      "```wlambda",
      "!x = std:to_ref 10;",
      "",
      "std:assert_eq (std:ser:wlambda x) \"$&&10\";",
      "",
      "std:assert_eq $*x 10;",
      "```",
      ""
    ]
  ],
  [
    "3.17.2 - std:ref:weaken _ref_",
    [
      "",
      "You can weaken any of those two types of references manually using the",
      "`std:ref:weaken` function.",
      "",
      "```wlambda",
      "!drop_check = $& $f;",
      "",
      "# Set `drop_check` to $true when all (non weak) references to it are gone.",
      "!x = $&& (std:to_drop {|| .drop_check = $true });",
      "",
      "# Create a weakened reference to the value referred to by x:",
      "!y = std:ref:weaken x;",
      "",
      "# The reference to the drop function is removed and this means",
      "# that the weak reference in y is invalidated and returns $n in future.",
      ".x = $n;",
      "",
      "# Deref y now gives you $n:",
      "std:assert_eq $*y $n;",
      "",
      "std:assert drop_check;",
      "```",
      "",
      "Please note that you can use `$w&`/`$weak&` as a shortcut to calling the library function:",
      "",
      "```wlambda",
      "!x      = $&& 10;",
      "!x_weak = $w& x;",
      "",
      "std:assert_eq x      &> type \"ref_strong\";",
      "std:assert_eq x_weak &> type \"ref_weak\";",
      "```",
      ""
    ]
  ],
  [
    "3.17.3 - std:ref:hide _value_",
    [
      "",
      "Creates a hidden reference from a given value or reference.",
      "",
      "```wlambda",
      "!r = $&& 10;            # strong ref to value 10",
      "",
      "# hide the reference for direct access via local variables",
      "!h = std:ref:hide r;",
      "",
      ".h += 11;",
      "",
      "std:assert_eq $*r       21;",
      "std:assert_eq h         21;",
      "std:assert_eq (std:write_str $:h) \"$&&21\";",
      "",
      "std:assert_eq (std:write_str $[r, $:h]) \"$[$<1=>$&&21,$<1>]\";",
      "```",
      ""
    ]
  ],
  [
    "3.17.4 - is_ref _value_",
    [
      "",
      "Returns `$true` if _value_ is a reference (strong, hidden or weak).",
      "",
      "```wlambda",
      "!x = $&&10;",
      "std:assert ~ is_ref ~ std:ref:weaken x;",
      "std:assert ~ is_ref $&10;",
      "std:assert ~ is_ref $&&10;",
      "",
      "std:assert ~ not ~ is_ref $[1,2,3];",
      "std:assert ~ not ~ is_ref ${a=10};",
      "std:assert ~ not ~ is_ref $true;",
      "std:assert ~ not ~ is_ref $none;",
      "```",
      ""
    ]
  ],
  [
    "3.17.5 - is_wref _value_",
    [
      "",
      "Returns `$true` if _value_ is a weak reference.",
      "",
      "```wlambda",
      "!x = $&& 10;",
      "!y = std:ref:weaken x;",
      "std:assert ~ is_wref y;",
      "std:assert ~ not ~ is_wref x;",
      "```",
      ""
    ]
  ],
  [
    "3.17.6 - std:ref:strengthen _ref_",
    [
      "",
      "You can convert a weak reference (weakened by `std:ref:weaken`) or a captured weak",
      "reference `$&` to strong with `std:ref:strengthen",
      "",
      "```wlambda",
      "!x = $&&10;",
      "!y = std:ref:weaken x;",
      "",
      ".x = $none;",
      "std:assert ~ is_none $*y;",
      "",
      ".x = $&&10;",
      ".y = std:ref:weaken x;",
      "!y2 = std:ref:strengthen y; # Here we take a second strong reference from a weak one",
      "",
      ".x = $none;",
      "std:assert ~ is_some $*y;",
      "std:assert ~ is_some $*y2;",
      "",
      ".y2 = $none;",
      "std:assert ~ is_none $*y;",
      "```",
      ""
    ]
  ],
  [
    "3.17.7 - std:ref:set _ref_ _value_",
    [
      "",
      "Sets the value of the reference _ref_ to _value_.",
      "If _ref_ is not a strong, hidden or weak reference nothing happens.",
      "",
      "Returns _value_ or `$none`.",
      "",
      "```wlambda",
      "!r1 = $&&1;",
      "std:ref:set r1 10;",
      "std:assert_eq $*r1 10;",
      "",
      "# Note that $& references in local variables are",
      "# automatically dereferenced. Because of that we need to wrap it into",
      "# an extra reference.",
      "!r2 = $& $& 1;",
      "std:ref:set r2 11;",
      "std:assert_eq $*r2 11;",
      "",
      "!r3 = $& $& 1;",
      "!w3 = std:ref:weaken r3;",
      "std:ref:set w3 14;      # Set reference via the weak reference in w3 to r3.",
      "std:assert_eq $*r3 14;",
      "```",
      ""
    ]
  ],
  [
    "3.18 - Iterators $iter _expression_",
    [
      "",
      "As a companion to the `iter` operation there are the iterator values.",
      "These are a special kind of values that generate a value when they are called.",
      "It supports to make an iterator from the same values as the `iter` operation.",
      "",
      "You can create an iterator from vectors and maps, but also specialized",
      "iterators that return a range of numbers or only keys of a map.",
      "About this see the section _Iterator Kinds_ below.",
      "",
      "The `$iter` syntax takes a complete expression as argument, that means",
      "you can directly write `$iter function arg1 arg2 ...` without",
      "delimiting the function call.",
      "",
      "Here is an example how to make an iterator over a vector:",
      "",
      "```wlambda",
      "!it = $iter $[1,2,3,4];",
      "",
      "!first  = it[];     # returns an optional value $o(1)",
      "!second = it[];     # returns an optional value $o(2)",
      "",
      "std:assert_eq first    $o(1);",
      "std:assert_eq second   $o(2);",
      "```",
      "",
      "You can also directly cast an iterator, which will also",
      "make it return a value:",
      "",
      "```wlambda",
      "!it = $iter $[1,2,3,4];",
      "",
      "std:assert_eq (int it)  1;",
      "std:assert_eq (int it)  2;",
      "```",
      "",
      "You can pass an iterator also to the `iter` operation:",
      "",
      "```wlambda",
      "!it = $iter $[1,2,3];",
      "",
      "!sum = 0;",
      "",
      "iter i it {",
      "    .sum = sum + i;",
      "};",
      "",
      "std:assert_eq sum 6;",
      "```",
      ""
    ]
  ],
  [
    "3.18.1 - Iterator Kinds",
    [
      "",
      "Here is a table of the behaviour of iterators created from WLambda data.",
      "",
      "| Data      | Iterator return values |",
      "|-----------|-----------|",
      "| vector  | Each element of the vector. |",
      "| map  | Each key/value pair of the map in undefined order. |",
      "| `$none`   | Returns nothing  |",
      "| optional | Returns the optional value on first invocation. |",
      "| `$o()` | Returns nothing. |",
      "| int  | Returns the integer value on first invocation. |",
      "| float  | Returns the integer value on first invocation. |",
      "| string | Returns the individual characters as string. |",
      "| symbol | Returns the individual characters as string. |",
      "| byte vector | Returns the individual bytes as byte vector. |",
      "| `$error`  | Returns the error value on first invocation. |",
      "| `$i(a, b)`  | The integers in the range of _a_ to _b_, not including _b_. |",
      "| `$i(a, b, step)`  | The integers in the range of _a_ to _b_ advanced by _step_, not including _b_. |",
      "| `$f(a, b)`  | The floats in the range of _a_ to _b_ advanced by `1.0`, not including _b_. |",
      "| `$f(a, b, step)`  | The floats in the range of _a_ to _b_ advanced by _step_, not including _b_. |",
      "| `$p(:enumerate, map)`  | Returns integers in the range of `0` to `len map`. |",
      "| `$p(:enumerate, vector)`  | Returns integers in the range of `0` to `len vector`. |",
      "| `$p(:values, map)`  | Returns the values of the _map_ in undefined order. |",
      "| `$p(:keys, map)`  | Returns the keys of the _map_ in undefined order. |",
      "| `$p(int_a, int_b)` | The same as `$i(a, b)`. This makes it possible to write `$iter 0 => 10`. |",
      "| `$p(iterator_a, iterator_b)` | Returns a zip operation of the elements returned by the iterator_a and iterator_b until one of both returns `$o()`. |",
      "| `$p(iterator, x)` | Returns a zip operation of the elements returned by the iterator and the newly created iterator`$iter x`. |",
      ""
    ]
  ],
  [
    "3.18.2 - Iterators on mutated data",
    [
      "",
      "Iterators hold a reference to the collection values. That means, if you mutate",
      "a vector while you iterate over it, it will not crash but it might produce",
      "weird effects.",
      "",
      "```wlambda",
      "!v = $[1,2,3];",
      "!it = $iter v;",
      "",
      "iter i v {",
      "    if i <= 3 {",
      "        std:push v i + 10;  # This is not recommended however...",
      "    };",
      "};",
      "",
      "std:assert_eq (str v) (str $[1, 2, 3, 11, 12, 13]);",
      "```",
      "",
      "This will also work for maps, but as the order of the map entries",
      "is undefined it will produce very indeterministic effects and it's really",
      "not recommended.",
      ""
    ]
  ],
  [
    "3.18.3 - Splicing an Iterator",
    [
      "",
      "You can directly insert the values produced by an iterator into a vector or map:",
      "",
      "```wlambda",
      "!it = $iter $[1,2,3,4];",
      "",
      "!v = $[10, 20, *it, 99];",
      "",
      "std:assert_eq (str v) (str $[10, 20, 1, 2, 3, 4, 99]);",
      "```",
      "",
      "Same goes for maps:",
      "",
      "```wlambda",
      "!it = $iter ${a = 10, b = 20};",
      "",
      "!m = ${ x = 99, *it };",
      "",
      "std:assert_eq m.a 10;",
      "std:assert_eq m.b 20;",
      "std:assert_eq m.x 99;",
      "```",
      ""
    ]
  ],
  [
    "3.18.4 - Calling an Iterator with a Function",
    [
      "",
      "When an iterator gets called with a function as first argument",
      "it will repeatedly call that function until no more values are",
      "available:",
      "",
      "```wlambda",
      "!it = $iter $[1,2,3];",
      "",
      "!sum = 0;",
      "",
      "it { .sum = sum + _ };",
      "",
      "std:assert_eq sum 6;",
      "```",
      ""
    ]
  ],
  [
    "3.18.5 - Zip Iterators",
    [
      "",
      "To highlight this feature from the table above: You can zip two iterators if",
      "you pass an iterator as first part of a pair `$p(a, b)`:",
      "",
      "```wlambda",
      "!v = $[\"a\", \"b\", \"c\"];",
      "",
      "!elems = $@vec",
      "    iter i $p($iter v, $iter $i(0, 10)) {",
      "        $+ i;",
      "    };",
      "",
      "std:assert_eq",
      "    (str elems)",
      "    (str $[$p(\"a\", 0), $p(\"b\", 1), $p(\"c\", 2)]);",
      "```",
      ""
    ]
  ],
  [
    "3.18.6 - is_iter _value_",
    [
      "",
      "Returns `$true` if _value_ is an iterator.",
      "",
      "```wlambda",
      "std:assert   (is_iter $iter $n);",
      "std:assert   (is_iter $iter 0 => 30);",
      "std:assert   not <& (is_iter $[1,2,3]);",
      "std:assert   (is_iter $iter $[1,2,3]);",
      "",
      "std:assert   (not <& is_iter <& $true);",
      "std:assert   (not <& is_iter <& $false);",
      "std:assert   (not <& is_iter <& 4);",
      "std:assert   (not <& is_iter <& $p(1, 2));",
      "```",
      ""
    ]
  ],
  [
    "3.19 - Calling Semantics of Data Types",
    [
      "",
      "You can call almost all basic data types of WLambda.",
      "Here is an overview of the data type calling semantics:",
      "",
      "| Type                         | Args                         | Semantics |",
      "|------------------------------|------------------------------|-----------|",
      "| `$none`                      | -                            | Any call to `$none` will result in a panic. |",
      "| `$error`                     | -                            | Any call to `$error` will result in a panic. |",
      "| function                     | *                            | Will call the function with the specified arguments. |",
      "| `$true`                      | `f1, f2`                     | Will call `f1`.          |",
      "| `$false`                     | `f1, f2`                     | Will call `f2` or return `$n` if `f2` is not provided.          |",
      "| `$true`                      | `$[1,2]`                     | Will return the second element `2` of the list. |",
      "| `$false`                     | `$[1,2]`                     | Will return the first element `1` of the list. |",
      "| integer                      | vector, string, byte_vec, iterator | Will return the element at the given integer index. |",
      "| symbol                       | map, userval                 | Will retrieve the value in the map at the key equal to the symbol. |",
      "| map                          | anything                     | Will call `anything` for each value and key in the map and return a list with the return values. |",
      "| string                       | string, byte_vec, char or byte | Append operation, works with multiple arguments. |",
      "| byte_vec                     | string, byte_vec, char or byte | Append operation, works with multiple arguments. |",
      "| string                       | `$p(int_offs, string/byte_vec/char/byte)` | Find operation, search from int_offs for the given string, byte_vec, char or byte. See also `std:str:find` and `std:bytes:find`. |",
      "| byte_vec                     | `$p(int_offs, string/byte_vec/char/byte)` | Find operation, search from int_offs for the given string, byte_vec, char or byte. See also `std:str:find` and `std:bytes:find`. |",
      "| `$p(char or byte, int_count)`| -                            | Create a string or byte_vec containing int_count of copies. |",
      "| `$p(int_offs, string/byte_vec/char/byte)` | string          | Find operation, search from int_offs for the given string, byte_vec, char or byte. |",
      "| `$p(int_offs, string/byte_vec/char/byte)` | byte_vec        | Find operation, search from int_offs for the given string, byte_vec, char or byte. |",
      "| `$p(int_from, int_count)`     | vector                      | Vector slice operation. |",
      "| `$i(int_from, int_count)`     | vector                      | Vector slice operation. |",
      "| `$p(int_from, int_count)`     | numeric vector              | Creates a vector slice from a numeric vector. |",
      "| `$i(int_from, int_count)`     | numeric vector              | Creates a vector slice from a numeric vector. |",
      "| `$p(int_from, int_count)`     | iterator                    | Iterator result list slice operation. |",
      "| `$i(int_from, int_count)`     | iterator                    | Iterator result list slice operation. |",
      "| `$p(int_from, int_count)`     | string                      | Substring operation. (See also section about pairs) |",
      "| `$i(int_from, int_count, ...)`| string                      | Substring operation. |",
      "| `$p(int_from, int_count)`     | byte_vec                    | Substring operation. (See also section about pairs) |",
      "| `$i(int_from, int_count, ...)`| byte_vec                    | Substring operation on the byte vector. |",
      "| string                       |`$i(int_from, int_count, ...)`| Substring operation. |",
      "| byte_vec                     |`$i(int_from, int_count, ...)`| Substring operation on the byte vector. |",
      "|`$p(string, int)`             | string                       | Split operation. (See also section about pairs) |",
      "|`$p(byte_vec, int)`           | byte_vec                     | Split operation. (See also section about pairs) |",
      "| string                       |`$p(string, int)`             | Split operation. |",
      "| byte_vec                     |`$p(byte_vec, int)`           | Split operation. |",
      "| string                       |`$p(string, string)`          | Replace all operation. |",
      "| byte_vec                     |`$p(byte_vec, byte_vec)`      | Replace all operation. |",
      "| `$p(string, string)`         | string                       | Replace all operation. (See also section about pairs) |",
      "| `$p(byte_vec, byte_vec)`     | byte_vec                     | Replace all operation. (See also section about pairs) |",
      "| `$p(pat_char, repl_char)`    | string or byte_vec           | Replace all pat_char in string or byte_vec with repl_char. |",
      "| `$p(pat_byte, repl_byte)`    | string or byte_vec           | Replace all pat_char in string or byte_vec with repl_char. |",
      "| `$p(char, char)`             | char or byte                 | Range check operation, whether char or byte is inside to/from range. |",
      "| `$p(byte, byte)`             | char or byte                 | Range check operation, whether char or byte is inside to/from range. |",
      "| `$p(int_a, int_b)`           | char or byte                 | Range check operation, whether char or byte is inside to/from range. |",
      "| `$i(int_a, int_b)`           | char or byte                 | Range check operation, whether char or byte is inside to/from range. |",
      "| char or byte                 |`$p(char, char)`              | Range check operation, whether char or byte is inside to/from range. |",
      "| char or byte                 |`$p(byte, byte)`              | Range check operation, whether char or byte is inside to/from range. |",
      "| char or byte                 |`$p(int_a, int_b)`            | Range check operation, whether char or byte is inside to/from range. |",
      "| char or byte                 |`$i(int_a, int_b)`            | Range check operation, whether char or byte is inside to/from range. |",
      "| `$o()`                       | -                            | Returns $none. |",
      "| `$o(x)`                      | -                            | Returns _x_. |",
      "| `$o()`                       | *                            | Calls $none with arguments, leading to a panic. |",
      "| `$o(x)`                      | *                            | Calls _x_ with the given arguments. |",
      "|                              |                              | |",
      ""
    ]
  ],
  [
    "4 - Conditional Execution - if / then / else",
    [
      ""
    ]
  ],
  [
    "4.1 - if/? _condition_ _then-expr_ [_else-expr_]",
    [
      "",
      "The keyword for conditional execution is either `if` or just the question mark `?`.",
      "It takes 3 arguments: The first is an expression that will be evaluated",
      "and cast to a boolean. If the boolean is `$true`, the second argument is",
      "evaluated. If the boolean is `$false` the thrid argument is evaluated.",
      "The third argument is optional.",
      "",
      "```wlambda",
      "!x = 10;",
      "",
      "!msg = \"x is \";",
      "if x > 4 {",
      "    .msg = std:str:cat msg \"bigger than 4\";",
      "} {",
      "    .msg = std:str:cat msg \"smaller than or equal to 4\";",
      "};",
      "",
      "std:assert_eq msg \"x is bigger than 4\";",
      "",
      "# You may also use `if` in case it suits your coding style better:",
      "if x == 10 {",
      "    std:assert $true;",
      "} {",
      "    std:assert $false;",
      "};",
      "```",
      "",
      "The _condition_ can also be a function block, which will be evaluated:",
      "",
      "```wlambda",
      "!res =",
      "    if { !x = 2; x > 1 } \"x > 1\";",
      "",
      "std:assert_eq res \"x > 1\";",
      "```",
      ""
    ]
  ],
  [
    "4.2 - Using Booleans for Conditional Execution",
    [
      "",
      "Conditional execution is also provided by the bool data type. As in WLambda",
      "everything can be called like a function, you can just pass other functions as",
      "arguments to `$true` and `$false`.  If you pass a function as first argument to",
      "`$true`, it will be executed. If you pass a function as second argument to",
      "`$false` then that will be executed.",
      "",
      "```wlambda",
      "(10 == 10) { std:displayln \"10 is 10\" };         #=> prints \"10 is 10\"",
      "(10 != 10) { std:displayln \"10 is not 10\" };     #=> doesn't print anything",
      "",
      "!x = 20;",
      "",
      "(x == 20) {",
      "    std:displayln \"x is 20\";",
      "} {",
      "    std:displayln \"x is 20\";",
      "}; # Do not forget the \";\"!",
      "```",
      "",
      "Actually, as the values `$true` and `$false` can be called like any other",
      "function you may write it also like this, which is not the recommended",
      "syntax, but still works:",
      "",
      "```wlambda",
      "(10 == 10)[{ std:displayln \"10 is 10\" }];",
      "",
      "!x = 21;",
      "(x == 20)[{ std:displayln \"x is 20\" }, { std:displayln \"x isn't 20\" }]; #=> print \"x isn't 20\"",
      "```",
      ""
    ]
  ],
  [
    "4.2.1 - pick _bool_ _a_ -b-",
    [
      "",
      "Often, you may want to choose one variable (_a_) or another (_b_) based on some predicate (_bool_).",
      "For these situations, the `pick` function is available.",
      "For example, perhaps you want to make a function which can take any number of parameters,",
      "or a single list parameter.",
      "",
      "```wlambda",
      "!sum = \\|| std:fold 0 { _ + _1 } ~ pick (is_vec _) _ @;",
      "```",
      ""
    ]
  ],
  [
    "4.2.2 - Indexing by Booleans",
    [
      "",
      "Booleans can also be used to index into lists.",
      "When this is done, `$t` represents `1` and `$f` represents `0`.",
      "This means that we can also express our `sum` function as:",
      "",
      "```wlambda",
      "!sum = \\|| std:fold 0 { _ + _1 } $[@, _].(is_vec _);",
      "```",
      "",
      "Furthermore, as `a.b` is equivalent to `b[a]`, one can also write this `sum` function",
      "by simply invoking `(is_vec _)` and passing in the list of options as a parameter.",
      "",
      "```wlambda",
      "!sum = \\|| std:fold 0 { _ + _1 } ~ (is_vec _) $[@, _];",
      "```",
      "",
      "When comparing the `pick` and indexing approaches it is important to note",
      "that the two possible return values are inverted:",
      "",
      "```wlambda",
      "!x = 20;",
      "!res = pick (x == 20) \"x is 20\" \"x isn't 20\";",
      "std:assert_eq res \"x is 20\";",
      "",
      ".res = $[\"x isn't 20\", \"x is 20\"].(x == 20);",
      "std:assert_eq res \"x is 20\";",
      "```",
      "",
      "With `pick`, the value to return in the `$t` case comes first, followed by the `$f` case's value,",
      "whereas with indexing approach, the opposite is true.",
      ""
    ]
  ],
  [
    "4.3 - Value matching with - match _value-expr_ ...",
    [
      "",
      "See also [8.1.1](#811-match-value-expr-match-pair1--default-expr) for a more",
      "comprehensive discussion of `match` and structure matchers.",
      "",
      "`match` allows for easily select from a set of values:",
      "",
      "```wlambda",
      "!check_fun = {",
      "    match _",
      "        20 =>   \"It's 20\"",
      "        30 =>   \"It's 20\"",
      "        \"No idea?\"",
      "};",
      "",
      "std:assert_eq check_fun[20] \"It's 20\";",
      "std:assert_eq check_fun[34] \"No idea?\";",
      "```",
      "",
      "Also works for deeper data structures:",
      "",
      "```wlambda",
      "!val = $[1, ${a = 10}, ${a = 10}, ${a = 10}, ${a = 10}, 2, 2, 2, 10];",
      "",
      "!res =",
      "    match val",
      "        $[1, _*, 3, 10] =>  :a",
      "        $[1, a ~ _* ${ a = y }, b ~ _+ 2, 10] => {",
      "            ${",
      "                a_elems = $\\.a,",
      "                a_value = $\\.y,",
      "                b_vals  = $\\.b,",
      "            }",
      "        };",
      "",
      "std:assert_str_eq res.a_elems $[${ a = 10 }, ${ a = 10 }, ${ a = 10 }, ${ a = 10 }];",
      "std:assert_str_eq res.a_value 10;",
      "std:assert_str_eq res.b_vals  $[2,2,2];",
      "```",
      ""
    ]
  ],
  [
    "5 - Loops And Iteration",
    [
      "",
      "WLambda has many ways to loop and iterate:",
      "",
      "- Counting loop with `range`",
      "- While some condition is `$true` with the `while` special form.",
      "- Over the items in a vector or map with the `iter` special form.",
      "- Calling an `$iter` iterator value with a function as first argument.",
      "- Over the items in a vector with either `for` or by calling the vector",
      "with a function as first argument.",
      "- Over the items in a map with either `for` or by calling the map",
      "with a function as first argument.",
      "- Over the characters in a string with either `for` or by calling it",
      "with a function.",
      "- Over the bytes in a byte vector with either `for` or by calling it",
      "with a function.",
      "",
      "`for` just iterates through the value and provides the individual items as first argument to the",
      "iteration function. But if you call the value with a function as first argument a mapping iteration",
      "is done. That means, the return value of the operation is a list with the return values of the",
      "iteration function. If you don't need that list you should use `for`.",
      ""
    ]
  ],
  [
    "5.1 - Control Flow",
    [
      ""
    ]
  ],
  [
    "5.1.1 - while _predicate_ _body_",
    [
      "",
      "`while` will evaluate _body_ until the evaluation of _predicate_ function returns `$false`.",
      "Or `break` is used to end the loop. The loop can be restarted using `next`.",
      "This is the most basic loop for iteration:",
      "",
      "```wlambda",
      "!i   = 0;",
      "!out = $[];",
      "",
      "while i < 10 {",
      "    std:push out i;",
      "    .i = i + 1;",
      "};",
      "",
      "std:assert_eq (str out) \"$[0,1,2,3,4,5,6,7,8,9]\";",
      "```",
      "",
      "If you need an endless loop you can pass `$true` as predicate:",
      "",
      "```wlambda",
      "!i = 0;",
      "",
      "while $true {",
      "    (i >= 4) break;",
      "    .i = i + 1;",
      "};",
      "",
      "std:assert_eq i 4;",
      "```",
      "",
      "The first ",
      ""
    ]
  ],
  [
    "5.1.2 - iter _var_ _iterable_ _body_",
    [
      "",
      "This is the primary syntax of WLambda to iterate over collections,",
      "numeric ranges and generally everything you can create an iterator from",
      "using the `$iter` syntax.",
      "",
      "The _var_ will be defined inside the _body_ and be filled with the",
      "value that was generated for the current iteration.",
      "And _iterable_ is everything that `$iter` can make an iterator from.",
      "Please refer to the section `Iterator Kinds` for a listing of this.",
      "",
      "Like usual, the control flow manipulators `next` and `break` also work",
      "for this kind of loop.",
      ""
    ]
  ],
  [
    "5.1.2.1 - Counting loop with _iter_",
    [
      "",
      "Here is an example how to iterate over a range from 1 to 9 and",
      "collect the sum of those integers using an accumulator:",
      "",
      "```wlambda",
      "!sum = $@int iter i $i(1,10) ~ $+ i;",
      "",
      "std:assert_eq sum 45;",
      "```",
      "",
      "Because `$iter $p(1, 10)` is the same as `$iter $i(1, 10)` and because",
      "there is the pair constructor operator `a => b`, the above can also be written as:",
      "",
      "```wlambda",
      "!sum = $@int iter i 1 => 10 ~ $+ i;",
      "",
      "std:assert_eq sum 45;",
      "```",
      ""
    ]
  ],
  [
    "5.1.2.2 - Vector iteration with _iter_",
    [
      "",
      "Here is a simple example of how to iterate over all items of a vector",
      "in order:",
      "",
      "```wlambda",
      "!sum = 0;",
      "",
      "iter i $[1,2,3,4,5,6] {",
      "    .sum = sum + i;",
      "};",
      "",
      "std:assert_eq sum 21;",
      "```",
      "",
      "Even if you pass the syntax for constructing a function to `iter` it will",
      "create a block of statements from it. So this will work too (also for `while` above):",
      "",
      "```wlambda",
      "!sum = 0;",
      "",
      "iter i $[1,2,3,4,5,6] \\.sum = sum + i;",
      "",
      "std:assert_eq sum 21;",
      "```",
      "",
      "However _body_ does not have to be a function definition or block, it can also",
      "be just a regular call argument:",
      "",
      "```wlambda",
      "!sum = 0;",
      "",
      "!inc = { .sum = sum + _; };",
      "",
      "iter i $[1,2,3,4] inc[i];",
      "",
      "std:assert_eq sum 10;",
      "```",
      "",
      "To iterate over a vector by index you can use this:",
      "",
      "```wlambda",
      "!v = $[1,2,3,4,5];",
      "!sum = 0;",
      "",
      "iter i $i(0, len v) {",
      "    .sum = sum + v.(i);",
      "};",
      "",
      "std:assert_eq sum 15;",
      "```",
      ""
    ]
  ],
  [
    "5.1.2.3 - Map iteration with _iter_",
    [
      "",
      "Iteration over a map is also easy and concise. The map entry",
      "will be represented using a pair value `$p(value, key)`.",
      "You can access the first and second element of a pair using the `v`/`value`",
      "and `k`/`key` keys of a pair (but also all other pair accessors defined",
      "in the section for pairs):",
      "",
      "```wlambda",
      "!sum = 0;",
      "",
      "iter i ${ a = 10, b = 20 } {",
      "    .sum = sum + i.v;",
      "};",
      "",
      "std:assert_eq sum 30;",
      "```",
      "",
      "Very useful for iterating just over the keys or values of a map can also be the",
      "special iterator values you get from the pair constructors:",
      "",
      "```wlambda",
      "!m = ${ a = 10, b = 20 };",
      "!sum = 0;",
      "",
      "iter v $p(:values, m) {",
      "    .sum = sum + v;",
      "};",
      "",
      "std:assert_eq sum 30;",
      "```",
      "",
      "Or if you need the keys:",
      "",
      "```wlambda",
      "!m = ${ a = 10, b = 20 };",
      "!sum = 0;",
      "",
      "iter k $p(:keys, m) {",
      "    std:displayln \"FOO\" k;",
      "    .sum = sum + m.(k);",
      "};",
      "",
      "std:assert_eq sum 30;",
      "```",
      ""
    ]
  ],
  [
    "5.1.2.4 - Closures and _iter_ `iter i ...`",
    [
      "",
      "If you need a new variable for capturing it in a closure on each",
      "iteration you need to make a new variable binding for each iteration:",
      "",
      "```wlambda",
      "!closures = $[];",
      "",
      "# Without the rebinding of the variable `i`, `i` would be captured as hidden",
      "# reference and each iteration would update the contents of that reference.",
      "iter i $i(0, 10) {",
      "    !i = i;",
      "    std:push closures { i * 10 };",
      "};",
      "",
      "std:assert_eq ($@i closures \\$+ _[]) 450;",
      "```",
      ""
    ]
  ],
  [
    "5.1.3 - range _start_ _end_ _step_ _fun_",
    [
      "",
      "`range` counts from _start_ to _end_ by increments of _step_ and calls _fun_",
      "with the counter. The iteration is inclusive, this means if _start_ == _end_",
      "the function _fun_ will be called once.",
      "",
      "In contrast to `iter` this is not a special syntax, but just a regular function",
      "that calls another function repeatedly. You can control it using the `break` and",
      "`next` functions however.",
      "",
      "```wlambda",
      "!out = $[];",
      "range 0 9 1 {!(i) = @;",
      "    std:push out i;",
      "};",
      "",
      "std:assert_eq (str out) \"$[0,1,2,3,4,5,6,7,8,9]\";",
      "```",
      "",
      "The construct also works for floating point numbers,",
      "but be aware of the inherent floating point errors:",
      "",
      "```wlambda",
      "!out = $[];",
      "range 0.3 0.4 0.01 {",
      "    std:push out ~ std:num:round 100.0 * _;",
      "};",
      "",
      "# 40 is not in the set because the accumulation of 0.01 results",
      "# in a value slightly above 0.4 and ends the range iteration:",
      "std:assert_eq (str out) \"$[30,31,32,33,34,35,36,37,38,39]\";",
      "```",
      ""
    ]
  ],
  [
    "5.1.4 - break _value_",
    [
      "",
      "`break` stops the inner most iterative construct, which then will return _value_.",
      "This should work for all repeatedly calling operations, such as",
      "`for`, `while`, `iter` and when calling lists directly. Also most library functions",
      "that iteratively call you react to it, like `std:re:map` and `std:re:replace_all`.",
      "Be aware, that returning a value might not be supported by all iterative constructs.",
      "",
      "```wlambda",
      "!ret = range 0 9 1 {!(i) = @;",
      "    (i > 4) { break :DONE };",
      "};",
      "",
      "std:assert_eq ret :DONE;",
      "```",
      "",
      "An example where the list iteration is stopped:",
      "",
      "```wlambda",
      "!val = $[1,2,3,4] { (_ > 3) { break :XX }; _ };",
      "",
      "std:assert_eq val :XX;",
      "```",
      ""
    ]
  ],
  [
    "5.1.5 - next",
    [
      "",
      "`next` stops execution of the current function or statement block and continues",
      "with the next iteration of the inner most iteration.",
      "",
      "```wlambda",
      "!sum = $@i $[1,2,3,4] {",
      "    (_ == 3) next;",
      "    $+ _;",
      "};",
      "std:assert_eq sum 7;",
      "```",
      "",
      "```wlambda",
      "!sum = $@i range 1 10 1 {",
      "    (_ % 2 == 0) next;",
      "    $+ _;",
      "};",
      "std:assert_eq sum 25;",
      "```",
      ""
    ]
  ],
  [
    "5.1.6 - jump _index-val_ _branch1_ ... _last-branch_",
    [
      "",
      "This is a jump table operation, it's a building block for the more",
      "sophisticated `match` operation. The first argument is an index into the table.",
      "If the index is outside the table the _last-branch_ is jumped to.  The branches",
      "are compiled like the bodies of `while`, `iter`, `match` and `if` into a runtime",
      "evaluated block.",
      "",
      "```wlambda",
      "!x   = 10;",
      "!idx = 2;",
      "",
      "!res =",
      "    jump idx",
      "        { x + 3 }",
      "        { x + 4 }",
      "        { x + 5 };",
      "",
      "std:assert_eq res 15;",
      "```",
      "",
      "The arms don't have to be in `{ ... }` because they are blocks",
      "and the above could be written like this:",
      "",
      "```wlambda",
      "!x   = 10;",
      "!idx = 2;",
      "",
      "!res =",
      "    jump idx",
      "        x + 3",
      "        x + 4",
      "        x + 5;",
      "std:assert_eq res 15;",
      "",
      "# or even this:",
      "!res = x + (jump idx 3 4 5);",
      "std:assert_eq res 15;",
      "```",
      ""
    ]
  ],
  [
    "5.2 - Collection Iteration",
    [
      ""
    ]
  ],
  [
    "5.2.1 - Iteration over vectors",
    [
      "",
      "Iterating over a vector is the most basic iteration supported by WLambda.",
      "You just call the vector with a function as first argument:",
      "",
      "```wlambda",
      "!sum = 0;",
      "$[1, 2, 3] {",
      "    .sum = sum + _;",
      "};",
      "",
      "std:assert_eq sum 6;",
      "```",
      "",
      "You can also use `for` if you like.",
      ""
    ]
  ],
  [
    "5.2.2 - Iteration over maps",
    [
      "",
      "Iterating over a map is as simple as iterating over a vector.",
      "The map can be called with a function as first argument and it starts",
      "iterating over its key/value pairs. The first argument of the",
      "function is the value, the second argument is the key.",
      "",
      "```wlambda",
      "!sum  = 0;",
      "!keys = $[];",
      "",
      "${a = 10, b = 20, c = 30} {",
      "    !(v, k) = @;",
      "    .sum = sum + v;",
      "    std:push keys k;",
      "};",
      "",
      "std:assert_eq sum 60;",
      "std:assert_eq (std:str:join \",\" ~ std:sort keys) \"a,b,c\";",
      "```",
      "",
      "You can also use `for` if you like.",
      ""
    ]
  ],
  [
    "5.2.3 - for _iteratable-value_ _function_",
    [
      "",
      "Calls _function_ for every element of _iteratable-value_.",
      "Iteratable values are:",
      "",
      "- Vectors",
      "```wlambda",
      "!product = 1;",
      "",
      "for $[3,4,5] {",
      "    .product = product * _;",
      "};",
      "",
      "std:assert_eq product 60;",
      "```",
      "- Maps",
      "```wlambda",
      "!product = 1;",
      "!keys    = $[];",
      "",
      "for ${a = 10, b = 20, c = 30} {",
      "    !(v, k) = @;",
      "    .product = product * v;",
      "    std:push keys k;",
      "};",
      "",
      "std:assert_eq (std:str:join \",\" ~ std:sort keys) \"a,b,c\";",
      "",
      "std:assert_eq product 6000;",
      "```",
      "- Byte Vectors",
      "```wlambda",
      "!byte_sum = 0;",
      "",
      "for $b\"abc\" {",
      "    .byte_sum = byte_sum + (int _);",
      "};",
      "",
      "std:assert_eq byte_sum 294;",
      "```",
      "- Strings",
      "```wlambda",
      "!str_chars = $[];",
      "",
      "for \"abc\" {",
      "    std:push str_chars _;",
      "};",
      "",
      "std:assert_eq (str str_chars) (str $['a', 'b', 'c']);",
      "```",
      "- Symbols",
      "```wlambda",
      "!str_chars = $[];",
      "",
      "for :abc {",
      "    std:push str_chars _;",
      "};",
      "",
      "std:assert_eq (str str_chars) (str $['a', 'b', 'c']);",
      "```",
      ""
    ]
  ],
  [
    "5.2.4 - map _function_ _iterable_",
    [
      "",
      "Maps anything that is _iterable_ by calling _function_ with each item as",
      "first argument and collecting the return values in a vector.",
      "",
      "If a map is passed as _iterable_ then _function_ is called with two arguments,",
      "the first being the map entry value and the second the key.",
      "Note: When iterating over maps, don't assume any order.",
      "",
      "It is very similar to `$@vec iter i <iterable> { $+ ... }`.",
      "",
      "```wlambda",
      "# Lists:",
      "",
      "std:assert_str_eq",
      "    (map { float[_] / 2.0 } $[1,2,3,4,5])",
      "    $[0.5, 1, 1.5, 2, 2.5];",
      "",
      "std:assert_str_eq",
      "    (map { _ * 10 } $[$b'a', $b'b', $b'c', 10, 20])",
      "    ($@vec",
      "        iter i $[$b'a', $b'b', $b'c', 10, 20] {",
      "            $+ i * 10",
      "        });",
      "",
      "# Great for working with strings too:",
      "",
      "std:assert_str_eq",
      "    (map std:str:to_uppercase",
      "        $[\"abc\", \"bcbc\", \"aaad\", \"afoo\", \"foo\"])",
      "    $[\"ABC\", \"BCBC\", \"AAAD\", \"AFOO\", \"FOO\"];",
      "",
      "# Maps:",
      "",
      "std:assert_str_eq",
      "    (std:sort ~ map { @ } ${a = 10, b = 20})",
      "    $[$[10, \"a\"], $[20, \"b\"]];",
      "",
      "# Generally anything that you can pass into `$iter`:",
      "",
      "std:assert_str_eq",
      "    (map { _ * 2 } 0 => 10)",
      "    $[0,2,4,6,8,10,12,14,16,18];",
      "",
      "```",
      ""
    ]
  ],
  [
    "5.2.5 - filter _function_ _iterable_",
    [
      "",
      "Filters anything that is _iterable_ by the given _function_.",
      "The _function_ is called with each item and if it returns a `$true` value,",
      "the item will be collected into a vector that is returned later.",
      "",
      "If a map is passed as _iterable_ then _function_ is called with two arguments,",
      "the first being the map entry value and the second the key.",
      "",
      "It is very similar to `$@vec iter i <iterable> { if some_function[_] { $+ ... } }`.",
      "",
      "```wlambda",
      "# Lists:",
      "",
      "std:assert_str_eq",
      "    (filter { (_ 0 1) == \"a\" } $[\"abc\", \"bcbc\", \"aaad\", \"afoo\", \"foo\"])",
      "    $[\"abc\",\"aaad\",\"afoo\"];",
      "",
      "# Good in combination with `map` too:",
      "",
      "std:assert_str_eq",
      "    (map std:str:to_uppercase",
      "        ~ filter { (_ 0 1) == \"a\" }",
      "            $[\"abc\", \"bcbc\", \"aaad\", \"afoo\", \"foo\"])",
      "    $[\"ABC\",\"AAAD\",\"AFOO\"];",
      "",
      "# Also like `map` works fine with maps, but the function",
      "# needs to take two arguments and returns a pair:",
      "",
      "std:assert_str_eq",
      "    (std:sort",
      "        ~ filter { @.0 % 2 == 0 }",
      "            ${a = 2, b = 43, c = 16, d = 13 })",
      "    $[16 => \"c\", 2 => \"a\"];",
      "",
      "# Generally anything that you can pass into `$iter`:",
      "",
      "std:assert_str_eq",
      "    (filter { _ % 2 == 0 } 0 => 10)",
      "    $[0,2,4,6,8];",
      "",
      "```",
      "",
      ""
    ]
  ],
  [
    "5.3 - Accumulation and Collection",
    [
      "",
      "WLambda provides special syntax and semantics for accumulating or collecting",
      "values while iterating through lists. There are following special syntax",
      "constructs:",
      "",
      "| Syntax            | Semantics |",
      "|-------------------|-----------|",
      "| $@v _expr_        | Setup collection of values in a vector, evaluates _expr_ and returns the vector. |",
      "| $@vec _expr_      | Same as $@v |",
      "| $@m _expr_        | Setup collection of key/value pairs in a map, evaluates _expr_ and returns the vector. |",
      "| $@map _expr_      | Same as $@m |",
      "| $@s _expr_        | Setup appending of values to a string, evaluates _expr_ and returns the string. |",
      "| $@string _expr_   | Same as $@s |",
      "| $@b _expr_        | Setup collection of values in a byte vector, evaluates _expr_ and returns byte vector. |",
      "| $@bytes _expr_    | Same as $@b |",
      "| $@i _expr_        | Setup accumulation in an integer, evaluates _expr_ and returns the integer sum. |",
      "| $@int _expr_      | Same as $@i |",
      "| $@f _expr_        | Setup accumulation in a float, evaluates _expr_ and returns the float sum. |",
      "| $@flt _expr_      | Same as $@f |",
      "| $+                | Evaluated to a function that can be called to add/append a new value to the current collection/accumulation. |",
      "| $@@               | Access the current accumulation value. |",
      "",
      "These syntaxes are not lexically scoped. That means `$+` and `$@@` can be used",
      "in other functions:",
      "",
      "```wlambda",
      "!out_mul = { $+ _ * 20 };",
      "",
      "!v = $@vec iter i $i(1,5) ~ out_mul i;",
      "",
      "std:assert_eq (str v) (str $[20, 40, 60, 80]);",
      "```",
      "",
      "However, due to issues with coupling your functions to the usage",
      "of accumulators this style is recommended:",
      "",
      "```wlambda",
      "!mul = { _ * 20 };",
      "",
      "!v = $@vec iter i $i(1,5) ~ $+ mul[i];",
      "",
      "std:assert_eq (str v) (str $[20, 40, 60, 80]);",
      "```",
      ""
    ]
  ],
  [
    "5.3.1 - Transforming a vector",
    [
      "",
      "If you just want to do something with items in a vector and",
      "construct a new one from the results:",
      "",
      "```wlambda",
      "!result = $@vec $[1,2,3,4] \\$+ _ * 2;   # multiply each item by 2",
      "",
      "std:assert_eq (str result)  \"$[2,4,6,8]\";",
      "```",
      ""
    ]
  ],
  [
    "5.3.2 - Example of `$@@`",
    [
      "",
      "Here is an interesting example how $@@ might be used:",
      "",
      "```wlambda",
      "",
      "!list_of_lists = $[];",
      "!result = $@vec $[1,2,3,4] {",
      "    $+ 2 * _;               # put the value into the list",
      "    std:push list_of_lists",
      "        ~ std:copy $@@; # construct a list of intermediate results",
      "};",
      "",
      "std:assert_eq (str result) \"$[2,4,6,8]\";",
      "",
      "std:assert_eq (str list_of_lists)",
      "    \"$[$[2],$[2,4],$[2,4,6],$[2,4,6,8]]\";",
      "```",
      ""
    ]
  ],
  [
    "5.3.3 - Transforming a vector to a map",
    [
      "",
      "For constructing maps the `$@map` construct is available.",
      "In the following example we transform a vector of pairs into a map:",
      "",
      "```wlambda",
      "",
      "!result = $@map $[ $[:a, 10], $[:b, 33], $[:c, 99] ] {",
      "    !(key, value) = _;",
      "    $+ key value;",
      "};",
      "",
      "std:assert_eq result.a 10;",
      "std:assert_eq result.b 33;",
      "std:assert_eq result.c 99;",
      "```",
      ""
    ]
  ],
  [
    "5.3.4 - Iteratively concatenating strings",
    [
      "",
      "In case you need to construct a longer text the `$@string` construct allows",
      "you to efficiently create a long string. For demonstration purposes",
      "we compare the following inefficient code with the usage of `$@string`:",
      "",
      "```wlambda",
      "# Inefficient example:",
      "",
      "!accum = \"\";",
      "$[\"abc\", \"def\", \"ghi\", \"XXX\"] {",
      "    .accum = accum _;   # allocates a new string each iteration",
      "};",
      "",
      "std:assert_eq accum \"abcdefghiXXX\";",
      "```",
      "",
      "In theory for this constructed example the quickest way would",
      "be to use `std:str:join`:",
      "",
      "```wlambda",
      "!accum = std:str:join \"\" $[\"abc\", \"def\", \"ghi\", \"XXX\"];",
      "",
      "std:assert_eq accum \"abcdefghiXXX\";",
      "```",
      "",
      "But maybe you need to transform or construct the strings before joining:",
      "",
      "```wlambda",
      "!transform = { \">\" _ };",
      "",
      "!accum = $@string $[\"abc\", \"def\", \"ghi\", \"XXX\"] {",
      "    $+[transform _] # appends the string to the accumulation string",
      "};",
      "",
      "std:assert_eq accum \">abc>def>ghi>XXX\";",
      "```",
      ""
    ]
  ],
  [
    "5.3.5 - Accumulating sums",
    [
      "",
      "The following examples show how accumulation of values with `$@int` and `$@float` work.",
      "",
      "```wlambda",
      "!sum = $@int $[1,2,3,4] {",
      "    $+ _",
      "};",
      "",
      "std:assert_eq sum 10;",
      "```",
      "",
      "And with floats:",
      "",
      "```wlambda",
      "!sum = $@float $[1.2,1.3,2.2,3.4] {",
      "    $+ _",
      "};",
      "",
      "std:assert_eq (std:num:round 10.0 * sum) 81.0;",
      "```",
      "",
      ""
    ]
  ],
  [
    "5.4 - Utilities",
    [
      ""
    ]
  ],
  [
    "5.4.1 - std:accum _collection_ _a_ _b_ ...",
    [
      "",
      "This function accumulates all its arguments in the _collection_.",
      "It does the same form of accumulation as `$+` does.",
      "",
      "```wlambda",
      "std:assert_eq (str ~ std:accum $[] 1 2 3)   \"$[1,2,3]\";",
      "std:assert_eq (std:accum \"\" 1 2 3)          \"123\";",
      "std:assert_eq (str ~ std:accum $b\"\" 1 2 3)  \"\\x01\\x02\\x03\";",
      "std:assert_eq (str ~ std:accum 10 1 2 3)    \"16\";",
      "```",
      ""
    ]
  ],
  [
    "5.4.2 - std:zip _vector_ _map-fn_",
    [
      "",
      "Creates a generator that calls _map_fn_ with the consecutive elements of _vector_",
      "as the last argument of _map-fn_. All arguments passed to std:zip",
      "are appended to the argument list.",
      "",
      "This is useful for combining the iteration over two vectors or collections.",
      "",
      "```wlambda",
      "!l = $@v $[13, 42, 97] ~ std:zip $[\"Foo\", \"Bar\", \"Baz\"] { $+ @ };",
      "std:assert_eq (str l) (str $[$[13, \"Foo\"], $[42, \"Bar\"], $[97, \"Baz\"]]);",
      "```",
      ""
    ]
  ],
  [
    "5.4.3 - std:fold _accumulator_ _func_ _iteratable_",
    [
      "",
      "This function iterates over _iteratable_ while providing the current element",
      "from _iteratable_ as first and the _accumulator_ variable to _func_ as second",
      "argument.",
      "The _accumulator_ for the next iteration is always the return value of the",
      "previous execution of _func_.",
      "",
      "This is a convenience function in cases where the accumulator syntax `$@`",
      "does not fit the use-case.",
      "",
      "Returns the most recently returned value from _func_.",
      "",
      "Calculate the product of the first 5 integers.",
      "",
      "```wlambda",
      "!v = std:fold 1 {!(x, acc) = @;",
      "    x * acc",
      "} $[1,2,3,4,5];",
      "",
      "std:assert_eq v 120;",
      "```",
      "",
      "Another contrived example:",
      "",
      "```wlambda",
      "!v = std:fold $[] {!(x, acc) = @;",
      "    std:displayln @;",
      "    ((std:cmp:str:asc \"c\" x) > 0) {",
      "        std:push acc x;",
      "    };",
      "    acc",
      "} \"abcdef\";",
      "",
      "std:assert_eq (str v) (str $['d', 'e', 'f']);",
      "```",
      ""
    ]
  ],
  [
    "5.4.4 - std:enumerate _map-fn_",
    [
      "",
      "Creates a generator that calls _map-fn_ with a counter that is incremented",
      "after each call, starting with 0. The counter is appended to the",
      "argument list after the regular arguments.",
      "",
      "```wlambda",
      "!l = $@v $[\"lo\", \"mid\", \"hi\"] ~ std:enumerate { $+ $[_1, _] };",
      "std:assert_eq (str l) (str $[$[0, \"lo\"], $[1, \"mid\"], $[2, \"hi\"]]);",
      "```",
      ""
    ]
  ],
  [
    "6 - Operators",
    [
      ""
    ]
  ],
  [
    "6.1 - Operator Assignment",
    [
      "",
      "Please note, that you can use all these operators, as well as special operators",
      "like `=>`, `&>` and `<&` with assignment operations:",
      "",
      "```wlambda",
      "!x = 10;",
      ".x += 3;",
      "std:assert_eq x 13;",
      "",
      "# also comparison operators work",
      "!y = 10;",
      ".y < = 10;",
      "std:assert_eq y $false;",
      "",
      "# function argument pipelining also works in this context",
      "!f = \\_ * 10;",
      ".f <&= 10;",
      "std:assert_eq f 100;",
      "",
      "!x = 10;",
      ".x &>= \\_ * 10;",
      "std:assert_eq f 100;",
      "```",
      ""
    ]
  ],
  [
    "6.2 - Arithmetic",
    [
      "",
      "The output type (float vs. integer) of the numerical arithmetic operators is defined",
      "by the _first_ operand of the operation. Use the casting functions `float` or",
      "`int` if you are unsure.",
      "",
      "Please note that not all operators are available as plain identifiers and need",
      "to be quoted when used in their prefix form or as functions, some of them are",
      "`*`, `/`, `%` and some others.",
      ""
    ]
  ],
  [
    "6.2.1 - + _operand-1_ _operand-2_ ...",
    [
      "",
      "This function implements arithmetic addition.  If the first operand is a",
      "float number, the substraction will return a float result. If it is an integer",
      "or anything else (like a string), an integer result is returned.",
      "",
      "```wlambda",
      "std:assert_eq (+ 5.5 0.5) 6.0;",
      "std:assert_eq (5.5 + 0.5) 6.0;",
      "std:assert_eq (+ 5 2) 7;",
      "std:assert_eq (+ \"5\" 2) 7;",
      "std:assert_eq (+ :5 2) 7;",
      "```",
      ""
    ]
  ],
  [
    "6.2.2 - - _operand-1_ _operand-2_ ...",
    [
      "",
      "This function implements arithmetic substraction.  If the first operand is a",
      "float number, the substraction will return a float result. If it is an integer",
      "or anything else (like a string), an integer result is returned.",
      "",
      "```wlambda",
      "std:assert_eq (- 5.5 0.5) 5.0;",
      "std:assert_eq (5.5 - 0.5) 5.0;",
      "std:assert_eq (- 5 2) 3;",
      "std:assert_eq (- \"5\" 2) 3;",
      "std:assert_eq (- :5 2) 3;",
      "```",
      ""
    ]
  ],
  [
    "6.2.3 - * _op-a_ _op-b_",
    [
      "",
      "Returns the multiplication of the two operands.",
      "",
      "```wlambda",
      "std:assert 10   * 4 == 40;",
      "std:assert 10.1 * 4 == 40.4;",
      "std:assert \"10\" * 4 == 40;",
      "",
      "std:assert (`*` 10 4) == 40;",
      "",
      "std:assert (float \"10.1\") * 4 == 40.4;",
      "```",
      ""
    ]
  ],
  [
    "6.2.4 - / _op-a_ _op-b_",
    [
      "",
      "Returns the division of the two operands.",
      "",
      "```wlambda",
      "std:assert 10   / 4 == 2;",
      "std:assert 10.0 / 4 == 2.5;",
      "std:assert \"10\" / 2 == 5;",
      "",
      "std:assert (`/` 10 4) == 2;",
      "",
      "std:assert (float \"10.1\") * 4 == 40.4;",
      "```",
      ""
    ]
  ],
  [
    "6.2.5 - % _op-a_ _op-b_",
    [
      "",
      "Returns the remainder of the division of _op-a_ by _op-b_.",
      "",
      "```wlambda",
      "std:assert     5 % 4 == 1;",
      "std:assert (`%` 5 4) == 1;",
      "```",
      ""
    ]
  ],
  [
    "6.2.6 - ^ _op-a_ _op-b_",
    [
      "",
      "Returns _op-a_ raised by the power of _op-b_.",
      "Supports float and integers.",
      "",
      "```wlambda",
      "std:assert_eq 2 ^ 4     16;",
      "std:assert_eq std:num:round[(2.0 ^ 2.1) * 1000] 4287.0;",
      "std:assert_eq 2 ^ 2.1   4; # first arg type matters!",
      "```",
      ""
    ]
  ],
  [
    "6.3 - Comparison",
    [
      ""
    ]
  ],
  [
    "6.3.1 - == _op-a_ _op-b_",
    [
      "",
      "Checks whether the two operands are equal to each other. Data types like",
      "booleans, integers, floats, symbols and strings are compared by their contents.",
      "Other types like vectors, maps, functions, errors or references are compared",
      "by referential equality.",
      "",
      "```wlambda",
      "std:assert              $none == $none;",
      "std:assert                  1 == 2 - 1;",
      "std:assert               \"aa\" == (\"a\" \"a\");",
      "std:assert               :xxy == :xxy;",
      "std:assert       not ~ $[1,2] == $[1,2];",
      "std:assert            $p(1,2) == $p(1,2);",
      "std:assert            $i(1,2) == $i(1,2);",
      "std:assert          $i(1,2,3) == $i(1,2,3);",
      "std:assert    not ~ $i(1,2,3) == $f(1.0,2.0,3.0);",
      "std:assert    $f(1.0,2.0,3.0) == $f(1.0,2.0,3.0);",
      "",
      "std:assert ~ `==` 1 (2 - 1); # prefix form",
      "```",
      ""
    ]
  ],
  [
    "6.3.2 - != _op-a_ _op-b_",
    [
      "",
      "Checks whether the two operands are distinct from each other.  Data types like",
      "booleans, integers, floats, symbols and strings are compared by their contents.",
      "Other types like vectors, maps, functions, errors or references are compared",
      "by referential equality.",
      "",
      "It's generally the opposite of `==`.",
      "",
      "```wlambda",
      "std:assert         1 != 2;",
      "std:assert     not[2 != 2];",
      "std:assert     \"foo\" != \"bar\";",
      "std:assert not[\"foo\" != \"foo\"];",
      "",
      "std:assert ~ `!=` 1 2;",
      "",
      "!r1 = $[1,2];",
      "!r2 = $[1,2];",
      "std:assert r1 != r2;",
      "```",
      ""
    ]
  ],
  [
    "6.3.3 - < _op-a_ _op-b_",
    [
      "",
      "Numerical comparison operator that checks whether _op-a_ is less than _op-b_",
      "",
      "```wlambda",
      "std:assert   10   < 11;",
      "std:assert   10.1 < 10.2;",
      "std:assert not[10 < 10.1];  # the type of the first argument decides return type!",
      "```",
      ""
    ]
  ],
  [
    "6.3.4 - <= _op-a_ _op-b_",
    [
      "",
      "Numerical comparison operator that checks whether _op-a_ is less or equal to _op-b_",
      "",
      "```wlambda",
      "std:assert 10   <= 11;",
      "std:assert 10.1 <= 10.2;",
      "std:assert 10   <= 10.1;  # integer <=, the type of the first argument decides return type!",
      "```",
      ""
    ]
  ],
  [
    "6.3.5 - > _op-a_ _op-b_",
    [
      "",
      "Numerical comparison operator that checks whether _op-a_ is greater than _op-b_",
      "",
      "```wlambda",
      "std:assert   11.1 > 11;",
      "std:assert   11.1 > 11.0;",
      "std:assert not[10 > 10.1];  # the type of the first argument decides return type!",
      "```",
      ""
    ]
  ],
  [
    "6.3.6 - >= _op-a_ _op-b_",
    [
      "",
      "Numerical comparison operator that checks whether _op-a_ is greater or equal to _op-b_",
      "",
      "```wlambda",
      "std:assert 11   >= 11;",
      "std:assert 10.2 >= 10.1;",
      "std:assert 10 >= 10.1;  # integer >=, the type of the first argument decides return type!",
      "```",
      ""
    ]
  ],
  [
    "6.4 - Bit Operations",
    [
      ""
    ]
  ],
  [
    "6.4.1 - & _op-a_ _op-b_",
    [
      "",
      "Binary `and` operation between two integers.",
      "",
      "```wlambda",
      "std:assert (0b0011 & 0b1011) == 0b011;",
      "std:assert (3      &     11) == 3;",
      "```",
      ""
    ]
  ],
  [
    "6.4.2 - &^ _op-a_ _op-b_",
    [
      "",
      "Binary `xor` operation between two integers.",
      "",
      "```wlambda",
      "std:assert (0b0011 &^ 0b1011) == 0b1000;",
      "std:assert (3      &^     11) == 8;",
      "```",
      ""
    ]
  ],
  [
    "6.4.3 - &| _op-a_ _op-b_",
    [
      "",
      "Binary `or` operation between two integers.",
      "",
      "```wlambda",
      "std:assert (0b0011 &| 0b1000) == 0b1011;",
      "std:assert (3      &|      8) == 11;",
      "```",
      ""
    ]
  ],
  [
    "6.4.4 - << _op-a_ _op-b_",
    [
      "",
      "Binary `left shift` operation of _op-a_ by _op-b_ bits.",
      "",
      "```wlambda",
      "std:assert (0b0011 << 3)   == 0b11000;",
      "std:assert (`<<` 0b1011 2) == 0b101100",
      "```",
      ""
    ]
  ],
  [
    "6.4.5 - >> _op-a_ _op-b_",
    [
      "",
      "Binary `right shift` operation of _op-a_ by _op-b_ bits.",
      "",
      "```wlambda",
      "std:assert (0b0011 >> 2)      == 0b0;",
      "std:assert (0b1100 >> 2)      == 0b11;",
      "std:assert (`>>` 0b1011000 3) == 0b1011",
      "```",
      ""
    ]
  ],
  [
    "6.5 - Collection Addition Operators +> and <+",
    [
      "",
      "`+>` and `<+` are special operators for convenient and quick collection creation.",
      "You can use them also to call a function with multiple arguments.",
      "",
      "```wlambda",
      "!vec = $[] +> 1 +> 2 +> 3;",
      "",
      "std:assert_str_eq vec $[1, 2, 3];",
      "",
      "!map = ${}",
      "    +> (:a => 1)",
      "    +> (:b => 2);",
      "",
      "map +> (:c => 3);",
      "",
      "std:assert_str_eq map ${a=1,b=2,c=3};",
      "```",
      "",
      "Usually these operators just append (`+>`) or prepend (`<+`) the right/left hand",
      "side to the collection. But there are some special values which do special things.",
      "",
      "First and foremost the iterator data type. If you pass an iterator to this",
      "operator, the iterator will be iterated and all returned elements are added",
      "to the collection in the order of the operator:",
      "",
      "```wlambda",
      "!v = $[] +> ($iter 0 => 4) +> ($iter \"abc\");",
      "",
      "std:assert_str_eq v $[0,1,2,3,'a','b','c'];",
      "```",
      "",
      "As the `<+` operator prepends the individual elements, the",
      "same is happening with the iterated elements. Which means",
      "that their order is reversed:",
      "",
      "```wlambda",
      "!v = ($iter 0 => 4) <+ ($iter \"abc\") <+ $[];",
      "",
      "std:assert_str_eq v $[3,2,1,0,'c','b','a'];",
      "```",
      "",
      "The following data types can be used as collection for",
      "these operators:",
      "",
      "- Vectors `$[]`",
      "- Maps `${}`",
      "- Strings `\"\"`",
      "- Byte vectors `$b\"\"`",
      "- Functions",
      "",
      "The most special cases are maps and functions, which are described",
      "in more detail in the next sections.",
      "",
      "#### Collection Addition with Maps",
      "",
      "If you add to a map, there is some special behavior for some data types.",
      "",
      "Adding a key value pair is done with pairs:",
      "",
      "```wlambda",
      "!m = ${}",
      "    +> $p(:a, 10)",
      "    +> :b => 20;",
      "",
      "std:assert_str_eq m ${a=10,b=20};",
      "```",
      "",
      "If you add an iterator, the iterator is walked and the given keys are",
      "added if present:",
      "",
      "```wlambda",
      "!m = ${}",
      "    +> ($iter $[1, 2, 3])",
      "    +> ($iter ${ a = 10, b = 20 });",
      "",
      "std:assert_str_eq m ${1=1,2=2,3=3,a=10,b=20};",
      "```",
      "",
      "If you add a list to a map, the first element of that list is used",
      "as key, and the list as value:",
      "",
      "```wlambda",
      "!m = ${}",
      "    +> $[:a, 1, 2]",
      "    +> $[:b, 3, 4];",
      "",
      "std:assert_str_eq m ${a=$[:a,1,2],b=$[:b,3,4]};",
      "```",
      "",
      "#### Collection Addition with Function",
      "",
      "If you pass a function as collection to either `+>` or `<+` the function",
      "is called for each added element. The return value of the expression",
      "is the return value of the most recent function call.",
      "",
      "```wlambda",
      "!v = $[];",
      "",
      "!v2 = { std:push v _; v } +> 1 +> 2 +> ${ a = 3, b = 4 };",
      "",
      "std:assert_str_eq v  $[1,2,${a=3,b=4}];",
      "std:assert_str_eq v2 $[1,2,${a=3,b=4}];",
      "```",
      ""
    ]
  ],
  [
    "6.5.1 - +> _collection_ _a_ ...",
    [
      "",
      "Append to collection operator.",
      "",
      "```wlambda",
      "!v  = $[] +> 1 +> \"x\" +> $b\"y\" +> ($iter 0 => 3);",
      "",
      "!v2 = `+>` $[] 1 \"x\" $b\"y\" ($iter 0 => 3);",
      "",
      "std:assert_str_eq v v2;",
      "```",
      ""
    ]
  ],
  [
    "6.5.2 - <+ _collection_ _a_ ...",
    [
      "",
      "Prepend to collection operator. Please note that the arguments are",
      "reversed to the order in an operator expression.",
      "",
      "```wlambda",
      "!v  = ($iter 0 => 3) <+ 1 <+ \"x\" <+ $b\"y\" <+ $[];",
      "",
      "!v2 = `<+` $[] $b\"y\" \"x\" 1 ($iter 0 => 3);",
      "",
      "std:assert_str_eq v v2;",
      "```",
      ""
    ]
  ],
  [
    "7 - String and Byte Vector Formatting",
    [
      "",
      "WLambda comes with a built in functionality for string (and byte vector)",
      "formatting.  It works by creating a specialized formatting function from a",
      "given string literal at compile time with the `$F\"...\"` syntax, or a string at",
      "runtime with the `std:formatter _str_` function.",
      "",
      "The formatter syntax is documented in detail at [12.2 String Formatting",
      "Syntax](#132-string-formatting-syntax). It is basically the Rust `std::fmt`",
      "Syntax with a few extensions for WLambda data types and the dynamically typed",
      "nature of WLambda.",
      "",
      "The WLambda syntax for `$F` is: `$F string-literal`. This means, you can",
      "use any WLambda string literal after `$F`:",
      "",
      "```wlambda",
      "$F\"...\";        # normal string",
      "$F$b\"...\";      # byte vector",
      "$F$q/.../;      # normal string, quote syntax",
      "$F$Q\"...\";      # byte vector quote syntax",
      "$F$code{ };     # code block string",
      "```",
      "",
      "(Please note, that `$code{ ... }` is not as useful in this context, because",
      "the formatter placeholders usually are not valid WLambda syntax.)",
      "",
      "This is a very simple example:",
      "",
      "```wlambda",
      "!x = \"abc\";",
      "!s = $F\"x = {}\" x;",
      "",
      "std:assert_eq s \"x = abc\";",
      "```",
      "",
      "You can also use string formatting to generate byte vectors:",
      "",
      "```wlambda",
      "!bv = $F$b\"x={}\" $b\"\\xFF\";",
      "",
      "std:assert_eq bv $b\"x=\\xFF\";",
      "```",
      "",
      "If you want to generate the WLambda written representation of a piece of",
      "data like `std:write_str` would return it, you have to specify the",
      "special formatting syntax `{:...!w}`:",
      "",
      "```wlambda",
      "std:assert_eq ($F\"x={:!w}\" $&&$[1, 2, 3, 4]) \"x=$&&$[1,2,3,4]\";",
      "",
      "# Without the `!w` the reference would just",
      "# be auto dereferenced like `str` would do it:",
      "std:assert_eq ($F\"x={}\"   $&&$[1, 2, 3, 4]) \"x=$[1,2,3,4]\";",
      "```",
      ""
    ]
  ],
  [
    "7.0.1 - std:formatter _format-string_",
    [
      "",
      "Returns a formatting function that takes exactly the arguments specified",
      "in the _format-string_. If the format syntax is wrong, an error is returned.",
      "",
      "This is useful, if you need to build a format string at runtime,",
      "because `$F` only allows string/byte vector literals.",
      "",
      "```wlambda",
      "!fmt = \">6.2\";",
      "!fmt_fun = (std:formatter (std:str:cat \"{1} [{0:\" fmt \"}]\"));",
      "",
      "std:assert_eq (fmt_fun 3.43554 1.2323) \"1.2323 [  3.44]\";",
      "```",
      ""
    ]
  ],
  [
    "7.1 - Formatting Numbers",
    [
      "",
      "Number formatting, that is integers, float and numerical vectors, require an",
      "extension of the formatting syntax. You need to specify whether an integer",
      "`\"{:...!i}\"` or a float `{:...!f}` is formatted. Otherwise WLambda will cast",
      "everything to a string for formatting.",
      "",
      "Here are some examples:",
      "",
      "```wlambda",
      "std:assert_eq ($F \"{:8!i}\"  123)   \"     123\";",
      "std:assert_eq ($F \"{:08!i}\" 123)   \"00000123\";",
      "std:assert_eq ($F \"{:<8!i}\" 123)   \"123     \";",
      "std:assert_eq ($F \"{:^8!i}\" 123)   \"  123   \";",
      "std:assert_eq ($F \"{:>8!i}\" 123)   \"     123\";",
      "",
      "std:assert_eq ($F \"{:8.2!f}\"  123.567)   \"  123.57\";",
      "std:assert_eq ($F \"{:08.2!f}\" 123.567)   \"00123.57\";",
      "std:assert_eq ($F \"{:<8.2!f}\" 123.567)   \"123.57  \";",
      "std:assert_eq ($F \"{:^8.2!f}\" 123.567)   \" 123.57 \";",
      "std:assert_eq ($F \"{:>8.2!f}\" 123.567)   \"  123.57\";",
      "",
      "# Note: For floats, the \"!f\" is implicit if you specify a precision:",
      "std:assert_eq ($F \"{:8.2}\"  123.567)   \"  123.57\";",
      "std:assert_eq ($F \"{:08.2}\" 123.567)   \"00123.57\";",
      "std:assert_eq ($F \"{:<8.2}\" 123.567)   \"123.57  \";",
      "std:assert_eq ($F \"{:^8.2}\" 123.567)   \" 123.57 \";",
      "std:assert_eq ($F \"{:>8.2}\" 123.567)   \"  123.57\";",
      "```",
      "",
      "You can even format numbers in numerical vectors, data vector, pairs or maps:",
      "",
      "```wlambda",
      "std:assert_eq ($F \"{:8.2}\" $f(1.2, 3.456, 8.232)) \"(    1.20,    3.46,    8.23)\";",
      "std:assert_eq ($F \"{:8.2}\" $[1.2, 3.456, 8.232])  \"[    1.20,    3.46,    8.23]\";",
      "std:assert_eq ($F \"{:8.2}\" $p(1.2, 3.456))        \"(    1.20,    3.46)\";",
      "std:assert_eq ($F \"{:8.2}\" ${x = 1.2, y = 3.456, z = 8.232})",
      "              \"{x:    1.20, y:    3.46, z:    8.23}\";",
      "",
      "std:assert_eq",
      "    ($F \"{:>8!i}\" $i(1.2, 3.456, 8.232))",
      "    \"(       1,       3,       8)\";",
      "```",
      "",
      "Also hexadecimal, octal and binary are supported for integers, they come after the `!i`:",
      "",
      "```wlambda",
      "std:assert_eq ($F \"{:5!ix}\" 321)    \"  141\";",
      "std:assert_eq ($F \"{:5!io}\" 321)    \"  501\";",
      "std:assert_eq ($F \"{:<11!ib}\" 321)  \"101000001  \";",
      "std:assert_eq ($F \"{:011!ib}\" 321)  \"00101000001\";",
      "```",
      ""
    ]
  ],
  [
    "8 - Data Structure Matchers, Selectors and String Patterns/Regex",
    [
      "",
      "WLambda comes with a builtin DSL (domain specific language) for",
      "shallow data structure matches and deep data structure selection and regular expression (regex) pattern",
      "matching on strings. A _selector_ (structure selection) gives you the",
      "ability to search deep into WLambda data structures like",
      "[CSS Selectors](https://www.w3.org/TR/selectors-3/) into HTML DOM trees",
      "or [XPath](https://www.w3.org/TR/xpath-31/) into XML.",
      "While a _structure matcher_, as used by the `match` operation,",
      "allows you to directly match a certain WLambda piece of data.",
      "",
      "A subset of the _selectors_ are the _patterns_, which are able to",
      "match strings like regular expressions. The syntax of _patterns_",
      "is a bit different from normal regular expressions like Perl,",
      "Python or JavaScript has. This is partly due to the fact that",
      "these patterns aim to be easily used to match parts of a specific",
      "string like filename globs `photo_???_*.jpg`.",
      "",
      "For an in depth description of the _selector_ and _pattern_ syntax",
      "please refer to the [Pattern and Selector Syntax](#821-selector-and-wlambda-regex-syntax).",
      ""
    ]
  ],
  [
    "8.1 - Data Structure Matcher",
    [
      "",
      "This is probably one of the most convenient matching features of WLambda.",
      "While selectors (`$S[a / * / b]`) allow searching deep into data structures,",
      "the matches allow to efficient precise shallow selection and matching.",
      "The `match` operation allows to match a value against multiple matchers,",
      "while the `$M ...` syntax allows to define a matcher function for a single",
      "match (commonly used in an if expression).",
      "",
      "For a reference of the matcher syntax see below.",
      ""
    ]
  ],
  [
    "8.1.1 - match _value-expr_ _match-pair1_ ... [_default-expr_]",
    [
      "",
      "The match operation is a very versatile control flow operation.",
      ""
    ]
  ],
  [
    "8.1.2 - $M _expr_",
    [
      "",
      "This is a structure matcher expression. It will compile _expr_ into a structure",
      "matcher function. The reslting function will match it's first argument agianst",
      "the match and return a map containing the capture variables (or just an empty map).",
      "",
      "It will also bind the result map to `$\\`. This makes it possible to easily match",
      "a data structure in an if statement:",
      "",
      "```wlambda",
      "!some_struct = $[:TEST, ${ a = 10, b = 1442 }];",
      "",
      "if some_struct &> ($M $[sym, ${ a = 10, b = x }]) {",
      "    std:assert_eq $\\.sym :TEST;",
      "    std:assert_eq $\\.x   1442;",
      "} {",
      "    panic \"It should've matched!\";",
      "};",
      "```",
      ""
    ]
  ],
  [
    "8.1.3 - Data Structure Matcher Syntax",
    [
      "",
      "This the the compiletime syntax that is understood by the",
      "structure matchers that are used by `$M ...` and `match`.",
      "",
      "- `$M`, `$M1`, `$M2`, ... in the following table stands for a structure matcher expression.",
      "- All other tokens or values stand for themself.",
      "",
      "| WLambda Value | Semantics |",
      "|-|-|",
      "| `x`                    | Matches any value and assigns it to the variable `x`. |",
      "| `?`                    | Matches any value, but does not assign it. |",
      "| `x $M $M1 ... $Mn`     | Assign the value that matched $M, $M1 or $Mn to the variable `x`. |",
      "| `? $M $M1 ... $Mn`     | Matches if $M, $M1 or $Mn matches. |",
      "| `_*`                   | Placeholder for 0 or N items that match any items in the vector. |",
      "| `_+`                   | Placeholder for 1 or N items that match any items in the vector. |",
      "| `_?`                   | Placeholder for 0 or 1 items that match any items in the vector. |",
      "| `_* $M`                | Placeholder for 0 or N items that match $M in the vector. |",
      "| `_+ $M`                | Placeholder for 1 or N items that match $M in the vector. |",
      "| `_? $M`                | Placeholder for 0 or 1 items that match $M in the vector. |",
      "| `_type? :integer ...`  | Matches an element of one of the given types.  Symbol names should have the same name as the type names returned by the `type` function. |",
      "| `$r/.../`              | Matches any element, where it's string contents matches the given pattern. |",
      "| `$rg/.../`             | Matches any element, where it's string contents matches the given pattern. Returns a list with all global matches. |",
      "| `$M1 &or $M2`          | Matches if $M1 or $M2 matches. |",
      "| `$M1 &and $M2`         | Matches if $M1 and $M2 matches. |",
      "| `$[$M1, $M2, ...]`     | Matches a vector. |",
      "| `${ $Mkey1 = $Mval1, ...}`| Matches a map. $Mkey1 can also be a $M match, but keep in mind that maps can only have symbols as keys. You can however match symbols using regex patterns for instance. If you only use symbols as keys in this match, the map access is optimized a bit, because there is no need to iterate over all keys then. |",
      "| `$p($M1, $M2)`         | Matches a pair. |",
      "| `$i($M1, ...)`         | Matches an integer vector. |",
      "| `$f($M1, ...)`         | Matches a float vector. |",
      "| `$o($M)`               | Matches an optional where the value matches $M. |",
      "| `$e $M`                | Matches an error value that matches $M. |",
      "| `$n`                   | Matches $none. |",
      "| literal values         | Literal values like booleans, strings, symbols and numbers match their value. |",
      ""
    ]
  ],
  [
    "8.2 - Data Structure Selectors `$S(...)`",
    [
      "",
      "This section shows how data structure selectors can be used.",
      "",
      "TODO",
      ""
    ]
  ],
  [
    "8.2.1 - Selector and WLambda Regex Syntax:",
    [
      "",
      "```ebnf",
      "    (* NOTE: Whitespace is not part of a pattern in most places. This means",
      "             if you want to match whitespace, you will have to escape",
      "             it either with a '\\', with a [ ] character class or match",
      "             one whitespace char with $s. *)",
      "",
      "    class_char  = { ?any character except \"]\"? }",
      "                  (* special sequence: \"\\^\" => \"^\" and \"\\\\\" => \"\\\"",
      "                     and \"\\]\" => \"]\" *)",
      "                ;",
      "",
      "    ident_char_in_selector =",
      "                  (* if regex is used inside a selector: *)",
      "                  { ?any character except whitespace,",
      "                    \"!\", \"?\", \"/\", \"\\\", \"|\", \"^\", \",\",",
      "                    \"'\", \"&\", \":\", \";\", \"$\", \"(\", \")\",",
      "                    \"{\", \"}\", \"[\", \"]\", \"*\" and \"=\"? }",
      "                  (* allows the usual backslash escaping from strings! *)",
      "                ;",
      "",
      "    ident_char_in_direct_pattern =",
      "                | (* if regex is used as pattern directly: *)",
      "                  { ?any character except whitespace,",
      "                    \"?\", \"|\", \"$\", \"(\", \")\", \"[\", \"]\" and \"*\"? }",
      "                  (* allows the usual backslash escaping from strings! *)",
      "                ;",
      "    ident_char  = ident_char_in_direct_pattern",
      "                | ident_char_in_selector",
      "                ;",
      "",
      "    ident       = ident_char, { ident_char }",
      "                ;",
      "",
      "    index       = digit, { digit }",
      "                ;",
      "",
      "    rx_atom     = pat_glob",
      "                | ident_char",
      "                ;",
      "",
      "    glob_atom   = pat_glob",
      "                | ident",
      "                ;",
      "",
      "    rx_match_mod = \"L\"             (* transforms the input string from the match",
      "                                      position on to lower case. *)",
      "                 | \"U\"             (* transforms the input string from the match",
      "                                      position on to upper case. *)",
      "                 ;",
      "",
      "    pat_regex   = \"*\", rx_atom     (* matches sub pattern 0 or N times *)",
      "                | \"+\", rx_atom     (* matches sub pattern 1 or N times *)",
      "                | \"<\", [ (\"*\" | \"+\" | \"?\") ], rx_atom",
      "                                   (* non greedy version of the above *)",
      "                | \"?\", rx_atom     (* matches sub pattern 0 or 1 times *)",
      "                | \"!\", rx_atom     (* matches (zero width) if next pattern does not match *)",
      "                | \"=\", rx_atom     (* matches (zero width) if next pattern does match *)",
      "                | \"^\"              (* matches (zero width) start of string *)",
      "                | \"$\"              (* matches (zero width) end of string *)",
      "                | \"s\"              (* matches one whitespace character *)",
      "                | \"S\"              (* matches one non-whitespace character *)",
      "                | \"&\", rx_match_mod",
      "                ;",
      "",
      "    glob_group  = \"(\", \"^\", pattern, \")\"    (* capturing sub group *)",
      "                | \"(\", pattern, \")\"         (* sub group *)",
      "                ;",
      "",
      "    class_range = class_char, \"-\", class_char (* contains a range of chars, eg. [a-z] *)",
      "                ;",
      "",
      "    glob_cclass = \"[\",  { class_char | class_range }, \"]\" (* character class match for 1 char *)",
      "                | \"[^\", { class_char | class_range }, \"]\" (* negated character class match for 1 char *)",
      "                ;",
      "",
      "    pat_glob    = \"*\"                       (* 0 or N any characters *)",
      "                | \"?\"                       (* any character *)",
      "                | \"$\", pat_regex",
      "                | glob_cclass",
      "                | glob_group",
      "                ;",
      "",
      "    pat_branch  = { glob_atom }",
      "                ;",
      "",
      "    pattern     = pat_branch, [ \"|\", pattern ]",
      "                ;",
      "",
      "    key         = index | pattern",
      "                ;",
      "",
      "    kv          = key, \"=\", pattern",
      "                ;",
      "",
      "    kv_item     = \"{\", kv, { \",\", kv }, \"}\"",
      "                ;",
      "",
      "    node_match  = \":\", [\"!\"], \"(\", selector, \")\"",
      "                | \":\", [\"!\"], kv_item",
      "                | \":\", [\"!\"], \"type\", \"=\", pattern",
      "                  (* pattern is matched against",
      "                     vval type as returned by `type` *)",
      "                | \":\", [\"!\"], \"str\",  \"=\", pattern",
      "                  (* pattern is matched against",
      "                     the string contents or stringified",
      "                     representation of the value *)",
      "                ;",
      "",
      "    node_cond   = node_match",
      "                | node_match, \"&\", node_cond",
      "                | node_match, \"|\", node_cond",
      "                ;",
      "",
      "    reckey_cond = \"!\", \"key\", \"=\", pattern",
      "                  (* recurse only into values if they are not referred",
      "                     to by a key matching the given pattern. *)",
      "                ;",
      "    recval_cond = \"=\", node_cond",
      "                  (* recurse only into values if they match the given",
      "                     condition *)",
      "                ;",
      "",
      "    node        = key, { node_cond }",
      "                  (* marks it for referencing it in the result set *)",
      "                | \"**\", [ reckey_cond ], [ recval_cond ], { node_cond }",
      "                  (* deep expensive recursion *)",
      "                | \"^\", node",
      "                ;",
      "",
      "    selector    = node, { \"/\", node }",
      "                ;",
      "```",
      ""
    ]
  ],
  [
    "8.2.2 - std:selector _string_",
    [
      "",
      "Parses the given _string_ as WLambda data structure selector and returns",
      "a function that takes a data structure as first argument. That function will",
      "then query the data structure according to the given selector.",
      "That function will also set the global variable `$\\` to the result.",
      "",
      "The main usage of this function is, when you want to define the selector",
      "at runtime. Otherwise WLambda provides the handy `$S(...)` syntax for",
      "generating the structure pattern function at compile time.",
      "",
      "```wlambda",
      "!runtime_name = \"foo\";",
      "!sel = std:selector (\" * / \" runtime_name);",
      "",
      "if sel <& $[${foo = 1}, ${foo = 2}, ${foo = 3}] {",
      "    std:assert_str_eq $\\ $[1,2,3];",
      "} {",
      "    std:assert $false",
      "};",
      "```",
      "",
      ""
    ]
  ],
  [
    "8.3 - String Patterns (Regex) `$r/.../`",
    [
      "",
      "This section shows how to use the builtin pattern regex engine",
      "in WLambda. You can embed patterns directly in your WLambda source",
      "with `$rQ...Q`. Where `Q` stands for the usual string quoting mechanism",
      "in WLambda (like `$q/foo/`, `$q(foo bar)`, ...). This has the advantage",
      "that the pattern syntax is checked on compile time of your WLambda program.",
      "",
      "The result of the expression `$r/foo/` is a function, which takes as first",
      "arguments a string and returns a vector of substrings of that input",
      "string. First element of that vector is always the matched sub string",
      "of the input string. All elements after that correspond to a pattern",
      "capture `(^...)` like in `$r/foo(^bar)/`.",
      "The function returns `$none` if the pattern could not be found in the input string.",
      "",
      "Lets start off with a simple example:",
      "",
      "```wlambda",
      "# Please note: Whitespace inside the pattern is allowed and will not be matched!",
      "",
      "!res = $r/a (^*) b/ \"fooaxxxxbber\";",
      "",
      "std:assert_eq res.0 \"axxxxbb\";",
      "std:assert_eq res.1 \"xxxxb\";",
      "```",
      "",
      "To match a whole string you can anchor using `$^` and `$$`:",
      "",
      "```wlambda",
      "!res = $r/$^ a (^*) b $$/ \"axxxxbb\";",
      "",
      "std:assert_eq res.0 \"axxxxbb\";",
      "std:assert_eq res.1 \"xxxxb\";",
      "```",
      "",
      "To match special the characters `$` you can use the backslash escaping `\\$`:",
      "",
      "```wlambda",
      "std:assert_eq ($r/$+ \\$/ \"FF$$$FF\").0   \"$$$\";",
      "```",
      "",
      "To access captured groups you can either use the return value of the",
      "matcher function, or use the global variable `$\\` which will contain",
      "the results of the latest match that was executed:",
      "",
      "```wlambda",
      "# Notice the usage of the `<&` function call operator:",
      "!res =",
      "    if \"foo//\\\\/foo\" &> $r| $<*? (^$+[\\\\/]) * | {",
      "        std:assert_eq $\\.0 \"foo//\\\\/foo\";",
      "",
      "        $\\.1",
      "    };",
      "",
      "std:assert_eq res \"//\\\\/\";",
      "```",
      ""
    ]
  ],
  [
    "8.3.1 - Global Patterns `$rg/.../`",
    [
      "",
      "With the `g` modifier the regex can be modified and will match the input",
      "string with the given pattern repeatedly and call a given function",
      "for each match.",
      "",
      "The match function will receive the input string as first argument",
      "and a function that will be called for each match as second argument.",
      "",
      "Inside the match function, you can use the control flow functions `break`",
      "and `next` to skip ahead.",
      "",
      "The match function receives the contents of `$\\` as first argument,",
      "the offset of the match in the input string as second argument",
      "and the length of the match as third argument:",
      "",
      "```wlambda",
      "!found = $@vec $rg/x(^?)y/ \"aax9yaaxcy\" {!(match, offs, len) = @;",
      "    $+ $[match.1, offs, len]",
      "};",
      "",
      "std:assert_str_eq found $[$[\"9\", 2, 3], $[\"c\", 7, 3]];",
      "```",
      ""
    ]
  ],
  [
    "8.3.2 - Pattern Substitutions `$rs/.../`",
    [
      "",
      "The `s` modifier creates a substitution that will substitute each match",
      "of the pattern in the given input string with the return value of the",
      "match function. The match function is called with the same values as `$rg`",
      "does.",
      "",
      "```wlambda",
      "!digits =",
      "    $[\"zero\", \"one\", \"two\", \"three\", \"four\",",
      "      \"five\", \"six\", \"seven\", \"eight\", \"nine\"];",
      "",
      "!ret = $rs/[0-9]/ \"on 1 at 0 of 8\" {!(match, offs, len) = @;",
      "    digits.(int match.0)",
      "};",
      "",
      "std:assert_eq ret \"on one at zero of eight\";",
      "```",
      "",
      "Inside the match function, you can use the control flow functions `break`",
      "and `next`. You can use that to control which occurence within the string to",
      "replace:",
      "",
      "```wlambda",
      "!res = $rs/xxx/ \"fxxxfxxxfxxxf\" { break \"O\" };",
      "",
      "std:assert_eq res \"fOfxxxfxxxf\";",
      "```",
      ""
    ]
  ],
  [
    "8.3.3 - Pattern Syntax Overview",
    [
      "",
      "While",
      "[Selector and WLambda Regex Syntax](#821-selector-and-wlambda-regex-syntax)",
      "describes the pattern syntax in detail,",
      "here is the WLambda pattern regex syntax in a nutshell:",
      "",
      "| Pattern Syntax | Semantics |",
      "|-|-|",
      "| `?|$()[]*`    | Many special chars are reserved in WLambda patterns. Be aware that more characters are reserved if you use the patterns in a data structure selector, instead of a single pattern. Please escape then using backslash like `\\\\/` or `[/]`.|",
      "| _whitespace_  | Please note, that whitespace to be matched must be escaped using '\\' or inside a character calss `[ ]`. |",
      "| `\\.`          | Backslash escapes work the same as in regular WLambda strings. `\\` escapes the following character to have no special syntactic meaning in a pattern except matching itself. While escape sequences like `\\x41` match the character `A` or `\\u{2211}` matches `∑`. These also work inside of character classes. |",
      "| `*`           | Match 0 to N occurences of any character. |",
      "| `?`           | Match 1 occurences of any character. |",
      "| `(...)`       | A match group (does not capture). |",
      "| `(^...)`      | A capturing match group. |",
      "| `[abcA-Z]`    | A character class, matching the listed characters or ranges. |",
      "| `[^abcA-Z]`   | A negative character class, matching all character except the listed characters or ranges. |",
      "| `$^`          | String start anchor. Matches only the start of the string. Useful for specifying patterns that match the complete string (in combination with `$$`). |",
      "| `$$`          | String end anchor. Matches only the end of the string. Useful for specifying patterns that must match the complete string. |",
      "| `$*X`         | Greedly matches the pattern part `X` 0 or N times. For grouping pattern parts use `(...)` like in `$*(abc)`. |",
      "| `$<*X`        | Non-greedly matches the pattern part `X` 0 or N times. |",
      "| `$+X`         | Greedly matches the pattern part `X` 1 or N times. For grouping pattern parts use `(...)` like in `$+(abc)`. |",
      "| `$<+X`        | Non-greedly matches the pattern part `X` 1 or N times. |",
      "| `$?X`         | Greedly matches 0 or 1 occurences of the pattern part `X`. Like usual, you can group using `(...)`. |",
      "| `$<?X`        | Non-greedly matches 0 or 1 occurences of the pattern part `X`. |",
      "| `$!X`         | Zero-width negative look-ahead. `($^$!a*)` matches any string not starting with an `a`.  |",
      "| `$=X`         | Zero-width positive look-ahead. `($^$=a*)` matches any string starting with an `a`. |",
      "| `$s`          | Matches one (Unicode) whitespace character. |",
      "| `$S`          | Matches one (Unicode) non-whitespace character. |",
      "| `$&L`         | Transforms the input string for the following pattern matching parts to lowercase (attention: O(n) operation on the complete rest of the string!). Useful for matching case-insensitively. |",
      "| `$&U`         | Transforms the input string for the following pattern matching parts to uppercase (attention: O(n) operation on the complete rest of the string!). Useful for matching case-insensitively. |",
      ""
    ]
  ],
  [
    "8.3.4 - Standard Regular Expressions",
    [
      "",
      "Please note that WLambda can optionally be compiled with the `regex` crate,",
      "which implements a more common syntax for regular expressions.",
      "Please refer to the functions `std:re:match` in the WLambda standard library",
      "for this.",
      ""
    ]
  ],
  [
    "8.3.5 - std:pattern _string_ [_mode_]",
    [
      "",
      "Compiles the regex pattern _string_ to a function just like `$r/.../` would do.",
      "The _mode_ can either be `:g` (global match like `$rg...`), `:s` (substitution",
      "like `$rs...`) or `$none`.  Useful for composing WLambda patterns at runtime:",
      "",
      "```wlambda",
      "!rx = std:pattern ~ std:str:cat \"(^\" \"$+\" \"[a-z]\" \")\";",
      "",
      "std:assert_eq (rx \"foo\").1 \"foo\";",
      "```",
      "",
      "Returns an error if the syntax failes to parse as pattern:",
      "",
      "```wlambda",
      "!err = unwrap_err ~ std:pattern \"($+[a-z]\";",
      "",
      "std:assert_eq $i(0, 11)[err] \"bad pattern\";",
      "```",
      "",
      "Here an example of substitution:",
      "",
      "```wlambda",
      "!subs = std:pattern \"$+x\" :s;",
      "std:assert_eq subs[\"fooxxxoxx\", \\\"a\"] \"fooaoa\";",
      "```",
      ""
    ]
  ],
  [
    "9 - Modules",
    [
      ""
    ]
  ],
  [
    "9.1 - export",
    [
      "",
      "```wlambda",
      "",
      "!expr = { _ + 30 };",
      "",
      "!@export symbol = expr; # exports symbol with value of expr (a function)",
      "",
      "```",
      "",
      "**Warning:** Do not expect the declared variables in the module to exist beyond",
      "execution time. Weak caught values will vanish like usual once the module scope",
      "is exited. This means, if you declare helper functions in local variables, do",
      "this with the `:global` modifier:",
      "",
      "```wlambda",
      "!:global helper = { _ * 2 };",
      "",
      "!@export doit = { helper 10 };",
      "```",
      "",
      "Alternatively make the helper a strong reference:",
      "",
      "```wlambda",
      "!helper = $&& { _ * 2 };",
      "",
      "!@export doit = { helper 10 };",
      "```",
      ""
    ]
  ],
  [
    "9.2 - import",
    [
      "",
      "```wlambda",
      "",
      "!@import x = tests:test_mod; # prefixes everything from modixes with x:",
      "",
      "std:assert ~ (x:symbol 10) == 40;",
      "",
      "```",
      "",
      "You can also skip the prefix:",
      "",
      "```wlambda",
      "!@import std;",
      "",
      "!v = $[];",
      "",
      "std:push v 10;",
      "std:push v 20;",
      "",
      "std:assert_eq (str v) \"$[10,20]\";",
      "```",
      ""
    ]
  ],
  [
    "10 - Core Library",
    [
      "",
      "This library contains all the core functions which belong to the",
      "core of the WLambda Programming Language. These functions can be seen",
      "as keywords of WLambda. Some functions are also available as operators.",
      ""
    ]
  ],
  [
    "10.0.1 - type _value_",
    [
      "",
      "Returns the name of the data type of _value_ as string.",
      "",
      "```wlambda",
      "std:assert_eq (type 10)         \"integer\";",
      "std:assert_eq (type 10.0)       \"float\";",
      "std:assert_eq (type {})         \"function\";",
      "!y = $&&std:to_drop { };",
      "std:assert_eq (type y)          \"drop_function\";",
      "std:assert_eq (type :s)         \"symbol\";",
      "std:assert_eq (type \"s\")        \"string\";",
      "std:assert_eq (type $[])        \"vector\";",
      "std:assert_eq (type ${})        \"map\";",
      "std:assert_eq (type $b\"\")       \"bytes\";",
      "std:assert_eq (type $n)         \"none\";",
      "std:assert_eq (type $t)         \"bool\";",
      "std:assert_eq (type $e $n)      \"error\";",
      "std:assert_eq (type $&&10)      \"ref_strong\";",
      "std:assert_eq (type $&10)       \"ref_hidden\";",
      "!x = $&&10;",
      "std:assert_eq (type ~ $w&x)     \"ref_weak\";",
      "```",
      ""
    ]
  ],
  [
    "10.0.2 - len _value_",
    [
      "",
      "Returns the length of _value_. Depending on the data type you will get",
      "different semantics.",
      "",
      "```wlambda",
      "# Always zero for scalar non sequential/collection values:",
      "std:assert_eq (len 10)              0;",
      "std:assert_eq (len 10.1)            0;",
      "std:assert_eq (len $t)              0;",
      "std:assert_eq (len $f)              0;",
      "std:assert_eq (len $n)              0;",
      "",
      "std:assert_eq (len \"\\xFF\")          2; # byte length of the UTF-8 string",
      "std:assert_eq (len $b\"\\xFF\")        1;",
      "std:assert_eq (len $[1,2,3,4,5])    5;",
      "std:assert_eq (len ${a=1, b=2})     2;",
      "std:assert_eq (len ${a=1, b=2})     2;",
      "```",
      ""
    ]
  ],
  [
    "10.0.3 - panic _message_",
    [
      "",
      "If your program runs into something that deserves a slap on the fingers",
      "of the developer you can use `panic` to do that.",
      ""
    ]
  ],
  [
    "11 - Standard Library",
    [
      ""
    ]
  ],
  [
    "11.0.1 - std:shuffle _rand_func_ _vec_",
    [
      "",
      "Shuffles the _vec_ in place. The function _rand_func_ needs to return",
      "a random 64 bit integer on each call. Here is an example:",
      "",
      "```wlambda",
      "std:srand 1234;",
      "!vec = $[1,2,3,4,5,6,7,8];",
      "std:shuffle { std:rand :i64 } vec;",
      "",
      "std:assert_eq (str vec) \"$[2,1,7,4,8,5,3,6]\";",
      "```",
      "",
      "An Example with std:rand:split\\_mix64\\_next:",
      "",
      "```wlambda",
      "!sm  = std:rand:split_mix64_new_from 1234;",
      "!vec = $[1,2,3,4,5,6,7,8];",
      "std:shuffle { std:rand:split_mix64_next sm } vec;",
      "",
      "std:assert_eq (str vec) \"$[2,1,7,4,8,5,3,6]\";",
      "```",
      ""
    ]
  ],
  [
    "11.0.2 - std:delete _vector-or-map_ _index-or-key_",
    [
      "",
      "This removes the designated element from the collection (either vector or map).",
      "This works for:",
      "",
      "- Vectors:",
      "```wlambda",
      "!v = $[1,2,3];",
      "",
      "std:assert_eq (std:delete v 1) 2;",
      "std:assert_eq (str v) (str $[1,3]);",
      "```",
      "- Maps:",
      "```wlambda",
      "!m = ${a = 10, b = 20};",
      "",
      "std:assert_eq (std:delete m :a) 10;",
      "std:assert_eq (str m) (str ${b = 20});",
      "```",
      "",
      "Please note that this operation is potentially O(n) on vectors.",
      ""
    ]
  ],
  [
    "11.0.3 - std:ref_id _value_",
    [
      "",
      "Returns an integer identifier for a given referential value.",
      "The ID will stay the same as long as the reference is allocated.",
      "This returns a value for all data types that have some form",
      "of internal reference to a value on the heap.",
      "",
      "The main usage of this function is to get a pre process unique ID",
      "for an allocated value. But be aware, that once the value is deallocated,",
      "the reference ID does not belong to that value anymore.",
      "",
      "```wlambda",
      "!v = $[1,2,3];",
      "",
      "!v_id1 = std:ref_id v;",
      "std:push v 4;",
      "",
      "!v_id2 = std:ref_id v;",
      "",
      "std:assert_eq v_id1 v_id2;",
      "```",
      ""
    ]
  ],
  [
    "11.0.4 - std:copy _vec_or_map_",
    [
      "",
      "Makes a shallow copy of the given vector or map.",
      "",
      "```wlambda",
      "!a = $[1,2,3];",
      "!b = std:copy a;",
      "b.0 = 10;",
      "",
      "std:assert_eq a.0 1;",
      "std:assert_eq b.0 10;",
      "```",
      ""
    ]
  ],
  [
    "11.0.5 - std:values _collection-or-iter_",
    [
      "",
      "This function returns all values in the given collection or iterator",
      "as vector. _collection-or-iter_ can have be one of the following data",
      "types:",
      "",
      "- vector",
      "- numerical float or integer vector",
      "- map",
      "- iterator `$iter`",
      "",
      "```wlambda",
      "std:assert_str_eq (std:values $iter 0 => 5)      $[0,1,2,3,4];",
      "std:assert_str_eq (std:values ${a = 10})         $[10];",
      "std:assert_str_eq (std:values $iter ${a = 10})   $[10];",
      "std:assert_str_eq (std:values $[1,2,3])          $[1,2,3];",
      "std:assert_str_eq (std:values $i(1,2,3))         $[1,2,3];",
      "```",
      ""
    ]
  ],
  [
    "11.0.6 - std:keys _collection-or-iter_",
    [
      "",
      "This function returns all keys in the given _collection_ or _iterator_.",
      "It's most useful for the map data type, but also returns the indices in",
      "a vector or numerical vector.",
      "",
      "```wlambda",
      "std:assert_str_eq (std:keys ${a = 10})           $[\"a\"];",
      "std:assert_str_eq (std:keys $iter ${a = 10})     $[\"a\"];",
      "std:assert_str_eq (std:keys $[3,3,3])            $[0,1,2];",
      "std:assert_str_eq (std:keys $i(4,4,4))           $[0,1,2];",
      "std:assert_str_eq (std:keys $i(4,4))             $[0,1];",
      "```",
      ""
    ]
  ],
  [
    "11.0.7 - std:sort [_compare_fun_] _vec_",
    [
      "",
      "Sorts the given _vec_ in place. The comparison function _compare_fun_ gets the",
      "two values a and b and needs to return -1 if a < b, 0 if a = b and 1 if a > b.",
      "",
      "There are four functions that implement numeric and lexicographic ordering:",
      "",
      "- `std:cmp:num:asc`",
      "- `std:cmp:num:desc`",
      "- `std:cmp:str:asc`",
      "- `std:cmp:str:desc`",
      "",
      "If no _compare_fun_ is given, the ordering will be ascending and lexicographic",
      "vs. numeric will be chosen by the type of the `a` value (if it is an integer or",
      "float it will be numeric, otherwise lexicographic).",
      "",
      "```wlambda",
      "!v = $[$[1], $[-1], $[3]];",
      "std:sort { std:cmp:num:desc _.0 _1.0 } v;",
      "",
      "std:assert_eq v.0.0 3;",
      "std:assert_eq v.1.0 1;",
      "std:assert_eq v.2.0 -1;",
      "```",
      ""
    ]
  ],
  [
    "11.0.8 - std:cmp:num:asc _a_ _b_",
    [
      "",
      "Compares _a_ and _b_ numerically and returns:",
      "",
      "| Cases         | Return Value |",
      "|---------------|--------------|",
      "| _a_ > _b_     | -1           |",
      "| _a_ == _b_    | 0            |",
      "| _a_ < _b_     | 1            |",
      "",
      "```wlambda",
      "std:assert_eq (std:cmp:num:asc 20 2)        -1;",
      "std:assert_eq (std:cmp:num:asc \"20\" \"20\")    0;",
      "std:assert_eq (std:cmp:num:asc 20 21)        1;",
      "```",
      ""
    ]
  ],
  [
    "11.0.9 - std:cmp:num:desc _a_ _b_",
    [
      "",
      "Compares _a_ and _b_ numerically descending and returns:",
      "",
      "| Cases         | Return Value |",
      "|---------------|--------------|",
      "| _a_ > _b_     | 1            |",
      "| _a_ == _b_    | 0            |",
      "| _a_ < _b_     | -1           |",
      "",
      "```wlambda",
      "std:assert_eq (std:cmp:num:desc \"20\" \"2\")     1;",
      "std:assert_eq (std:cmp:num:desc \"20\" \"20\")    0;",
      "std:assert_eq (std:cmp:num:desc 20 21)       -1;",
      "```",
      ""
    ]
  ],
  [
    "11.0.10 - std:cmp:str:asc _a_ _b_",
    [
      "",
      "Compares _a_ and _b_ lexicographically by their byte values. This orders",
      "Unicode code points based on their positions in the code charts.",
      "",
      "| Cases         | Return Value |",
      "|---------------|--------------|",
      "| _a_ > _b_     | -1           |",
      "| _a_ == _b_    | 0            |",
      "| _a_ < _b_     | 1            |",
      "",
      "```wlambda",
      "std:assert_eq (std:cmp:str:asc \"abc\" \"aba\") -1;",
      "std:assert_eq (std:cmp:str:asc \"abc\" \"abc\")  0;",
      "std:assert_eq (std:cmp:str:asc \"abc\" \"abd\")  1;",
      "```",
      ""
    ]
  ],
  [
    "11.0.11 - std:cmp:str:desc _a_ _b_",
    [
      "",
      "Compares _a_ and _b_ lexicographically by their byte values. This orders",
      "Unicode code points based on their positions in the code charts.",
      "",
      "| Cases         | Return Value |",
      "|---------------|--------------|",
      "| _a_ > _b_     | 1            |",
      "| _a_ == _b_    | 0            |",
      "| _a_ < _b_     | -1           |",
      "",
      "```wlambda",
      "std:assert_eq (std:cmp:str:desc \"abc\" \"aba\")  1;",
      "std:assert_eq (std:cmp:str:desc \"abc\" \"abc\")  0;",
      "std:assert_eq (std:cmp:str:desc \"abc\" \"abd\") -1;",
      "```",
      ""
    ]
  ],
  [
    "11.0.12 - std:reverse _value_",
    [
      "",
      "Reverses the given sequence of values. This works for following data types:",
      "",
      "- Strings",
      "- Byte vectors",
      "- Vectors",
      "- Numeric vectors",
      "- Iterators",
      "",
      "```wlambda",
      "std:assert_str_eq (std:reverse $[1, 2, 3, 4])       $[4,3,2,1];",
      "std:assert_str_eq (std:reverse \"ABC\")               \"CBA\";",
      "std:assert_str_eq (std:reverse $b\"ABC\")             $b\"CBA\";",
      "std:assert_str_eq (std:reverse $i(1,2,3,4))         $i(4,3,2,1);",
      "std:assert_str_eq (std:reverse $f(1.1,2.2,3.3,4.4)) $f(4.4,3.3,2.2,1.1);",
      "```",
      ""
    ]
  ],
  [
    "11.0.13 - std:displayln _arg1_ ...",
    [
      "",
      "This function writes a humand readable version of all the arguments",
      "(with a space inbetween) to the standard output. This means that:",
      "",
      "```text",
      "std:displayln \"foo\"",
      "```",
      "",
      "Will just print `foo` and a newline.",
      "",
      "If you need a less ambigous form, use `std:writeln`, which",
      "handles its argument like written via `std:ser:wlambda` instead of `str`.",
      ""
    ]
  ],
  [
    "11.0.14 - $DEBUG _arg1_ ...",
    [
      "",
      "This is a special value that evaluates to a print function that supplies the",
      "current position in the source code. For example this:",
      "",
      "```wlambda",
      "!k = $[1, 2, 3];",
      "",
      "$DEBUG \"I got values:\" k 99;",
      "```",
      "",
      "Will print this (assuming it's at line 1 col 3 in file `file_foo.wl`):",
      "",
      "```text",
      "[1,3:<file_foo.wl>] DEBUG: \"I got values:\"(string) $[1,2,3](vector) 99(integer)",
      "```",
      "",
      "In case you want to directly write a string or some value, you will have",
      "to prefix the argument with the symbol `:\\`:",
      "",
      "```wlambda",
      "!k = 30;",
      "$DEBUG :\\ \"k =\" :\\ k;",
      "```",
      "",
      "Will print like this:",
      "",
      "```text",
      "[1,11:<wlambda::eval>] DEBUG: k = 30",
      "```",
      ""
    ]
  ],
  [
    "11.0.15 - std:writeln _arg1_ ...",
    [
      "",
      "This function writes the WLambda representation of its arguments",
      "(with a space inbetween) to standard output. This means that:",
      "",
      "```text",
      "std:displayln \"foo\"",
      "```",
      "",
      "Will print `\"foo\"` and a newline.",
      "",
      "See also the description of `std:ser:wlambda`.",
      "",
      "If you need a more human readable form use `std:displayln`.",
      ""
    ]
  ],
  [
    "11.0.16 - std:eval _code-string_",
    [
      "",
      "Evaluates _code-string_ in the current global environment and returns",
      "the generated value. If the code leads to any kind of evaluation error,",
      "an error object is returned.",
      "",
      "```wlambda",
      "std:assert_eq (std:eval \"1 + 2\") 3;",
      "!:global X = 20;",
      "std:assert_eq (std:eval \"1 + X\") 21;",
      "```",
      ""
    ]
  ],
  [
    "11.0.17 - std:assert _bool_ \\[_message_]",
    [
      "",
      "Just a simple assertion function that panics if the first argument is not true.",
      "Returns the passed value if it is a true value.",
      "You can pass an optional message as second parameter.",
      "",
      "```norun_wlambda",
      "std:assert $false; #=> Panic",
      "std:assert 120;    #=> 120",
      "```",
      ""
    ]
  ],
  [
    "11.0.18 - std:assert_eq _actual_ _expected_ \\[_message_]",
    [
      "",
      "This function checks if the _actual_ value is equal to the",
      "_expected_ value and panics if not. The optional _message_ is",
      "passed in the panic for reference.",
      "",
      "```wlambda",
      "!x = 30 * 2;",
      "std:assert_eq x 60 \"30 * 2 == 60\";",
      "```",
      ""
    ]
  ],
  [
    "11.0.19 - std:assert_str_eq _actual_ _expected_",
    [
      "",
      "This function stringifies _actual_ and _expected_ using the `str` function",
      "and compares the resulting strings.",
      "",
      "This is very useful to compare data structures, as map keys are sorted",
      "if the maps are stringified using `str`:",
      "",
      "```wlambda",
      "std:assert_str_eq $[1, 2, 3]        $[1, 2, 3];",
      "```",
      ""
    ]
  ],
  [
    "11.0.20 - std:assert_rel_eq _l_ _r_ _epsilon_ \\[_message_]",
    [
      "",
      "This function checks if `l` is within `epsilon` of `r`.",
      "If the absolute value of the difference between `l` and `r` is greater than `epsilon`,",
      "this function will panic, also displaying the optional message if present.",
      "",
      "```wlambda",
      "# these two are within 1 of each other",
      "!x = 10.5;",
      "!y = 11.3;",
      "std:assert_rel_eq x y 1;",
      "",
      "# but not within 0.5 of each other, so this line is commented out.",
      "# std:assert_eq x y 0.5;",
      "```",
      ""
    ]
  ],
  [
    "11.0.21 - std:measure_time _unit_ _function_",
    [
      "",
      "This function measures the time the given _function_ took to execute.",
      "The _unit_ defines how precisely the time is measured. Following strings are supported",
      "units:",
      "",
      "- `s` - seconds",
      "- `ms` - milliseconds",
      "- `us` - microseconds",
      "- `ns` - nanoseconds",
      "",
      "The return value is a vector where the first element is the",
      "time it took to execute the function, and the second element is the",
      "return value of that function.",
      "",
      "```wlambda",
      "!res = std:measure_time :ns { $@i iter i 0 => 100000 { $+ i } };",
      "std:assert res.0 > 100;",
      "std:assert_eq res.1 4999950000;",
      "```",
      ""
    ]
  ],
  [
    "11.1 - I/O",
    [
      ""
    ]
  ],
  [
    "11.1.1 - std:io:line",
    [
      "",
      "Reads a line from standard input and returns it. Returns an error if something",
      "went wrong.",
      "",
      "```text",
      "!line = unwrap std:io:line[];",
      "std:displayln \"you entered: \" std:str:trim_end[line];",
      "```",
      ""
    ]
  ],
  [
    "11.1.2 - std:io:lines [_value_]",
    [
      "",
      "Calls the given _value_ for each line in standard input until EOF and returns",
      "the last returned value from that call.  If _value_ is not given, all lines",
      "will be appended to a new vector and returned.  Returns an error if some IO",
      "error occured.",
      "",
      "```text",
      "!lines = std:io:lines[];",
      "",
      "!lines = $@v std:io:lines $+;",
      "",
      "std:io:lines {!(line) = @;",
      "    std:displayln \"You entered: [\" std:str:trim[line] \"]\";",
      "};",
      "```",
      ""
    ]
  ],
  [
    "11.1.3 - std:io:file:read_text _filename_",
    [
      "",
      "Opens the file _filename_ and returns its contents interpreted as UTF8",
      "text as string.",
      "",
      "```wlambda",
      "std:io:file:write_safe \"prelude_test.txt\" \"abcäöü\";",
      "",
      "!t = std:io:file:read_text \"prelude_test.txt\";",
      "std:assert_eq t \"abcäöü\" \"reading text from file works\";",
      "```",
      ""
    ]
  ],
  [
    "11.1.4 - std:io:file:read _filename_",
    [
      "",
      "Opens the file _filename_ and returns its contents as byte buffer.",
      "",
      "```wlambda",
      "std:io:file:write_safe \"prelude_test.txt\" \"abcäöü\";",
      "",
      "!t = std:io:file:read \"prelude_test.txt\";",
      ".t = std:str:from_utf8 t;",
      "std:assert_eq t \"abcäöü\" \"reading binary from file works\";",
      "```",
      ""
    ]
  ],
  [
    "11.1.5 - std:io:file:write_safe _filename_ _bytes-or-string_",
    [
      "",
      "Creates a new file with the given filename but with a \"~\" appended",
      "and writes the contents into it. After successful write, it renames",
      "the file to the given filename.",
      ""
    ]
  ],
  [
    "11.1.6 - std:io:file:append _filename_ _bytes-or-string_",
    [
      "",
      "Opens the given filename in append mode and appends _bytes-or-string_ to the",
      "end of the file.",
      ""
    ]
  ],
  [
    "11.1.7 - std:io:stdout:newline",
    [
      "",
      "Writes a newline to standard output. Returns an error if an error occured or",
      "`$true` otherwise.",
      ""
    ]
  ],
  [
    "11.1.8 - std:io:stdout:flush",
    [
      "",
      "Flushes the standard output buffer. Returns an error if an error occured or",
      "`$true` otherwise.",
      ""
    ]
  ],
  [
    "11.1.9 - std:io:stdout:print _value_",
    [
      "",
      "Writes the given _value_ to standard output in a human readable form like `std:displayln`",
      "does. Returns an error if an error occured. `$true` if everything is fine.",
      "",
      "```text",
      "std:io:stdout:write \"xxx\"; # => Writes `xxx` to standard output",
      "```",
      ""
    ]
  ],
  [
    "11.1.10 - std:io:stdout:write _value_",
    [
      "",
      "Writes a WLambda representation of _value_ to standard output.",
      "Returns an error if an error occured. `$true` if everything is fine.",
      "",
      "```text",
      "std:io:stdout:write \"xxx\"; # => Writes `\"xxx\"` to standard output",
      "```",
      ""
    ]
  ],
  [
    "11.1.11 - std:io:flush _handle_",
    [
      "",
      "Flushes the internal buffers of _handle_. _handle_ can be any kind of IO handle,",
      "like a file handle or networking socket.",
      "",
      "```text",
      "!socket = unwrap ~ std:net:tcp:connect \"127.0.0.1:80\";",
      "",
      "std:io:write socket $b\"GET / HTTP/1.0\\r\\n\\r\\n\";",
      "std:io:flush socket;",
      "```",
      ""
    ]
  ],
  [
    "11.1.12 - std:io:read_some _handle_",
    [
      "",
      "Reads some amount of data from _handle_. The default maximum amount",
      "of bytes read is 4096. This function returns `$o(bytes)` if something",
      "was read. It returns `$o()` when EOF is encountered. `$none` is",
      "returned when the IO operation was interrupted or did timeout.",
      "An `$error` is returned if some kind of error happened, like loss of",
      "TCP connection.",
      "",
      "Here is an example how to read everything from a socket until EOF is",
      "encountered:",
      "",
      "```text",
      "!socket = unwrap ~ std:net:tcp:connect \"127.0.0.1:80\";",
      "",
      "std:io:write socket $b\"GET / HTTP/1.0\\r\\n\\r\\n\";",
      "std:io:flush socket;",
      "",
      "!buf = $b\"\";",
      "!done = $f;",
      "while not[done] {",
      "    match std:io:read_some[socket]",
      "        $o(buf) => { .buf = buf +> $\\.buf; }",
      "        $o()    => { .done = $t; }",
      "        ($e _)  => { .done = $t; };",
      "};",
      "```",
      ""
    ]
  ],
  [
    "11.1.13 - std:io:write _handle_ _data_ [_offs_]",
    [
      "",
      "Write all data as byte vector to the IO _handle_ (socket, file handle, ...),",
      "starting at _offs_ (0 default).",
      "Returns the number of bytes written, an error or `$none` if interrupted.",
      "Note: This function does not respect the underlying write timeout in _handle_ properly.",
      "",
      "```text",
      "!socket = unwrap ~ std:net:tcp:connect \"127.0.0.1:80\";",
      "",
      "std:io:write socket $b\"GET / HTTP/1.0\\r\\n\\r\\n\";",
      "```",
      ""
    ]
  ],
  [
    "11.1.14 - std:io:write_some _handle_ _data_",
    [
      "",
      "Try to write some data as byte vector to the IO _handle_ (socket, file handle,",
      "...), starting at _offs_ (0 default).",
      "Returns the number of bytes written, an error or `$none` if a timeout or interrupt",
      "ended the write operation.",
      "",
      "```text",
      "!socket = unwrap ~ std:net:tcp:connect \"127.0.0.1:80\";",
      "",
      "!bytes = $b\"GET / HTTP/1.0\\r\\n\\r\\n\";",
      "!written = 0;",
      "",
      "while len[bytes] > written {",
      "    match (std:io:write_some socket bytes written)",
      "        $o(n)  => { .written += n; }",
      "        $none  => {}",
      "        ($e _) => { break[] };",
      "}",
      "```",
      ""
    ]
  ],
  [
    "11.2 - Networking",
    [
      ""
    ]
  ],
  [
    "11.2.1 - std:net:tcp:connect _socket-addr_ [_connect-timeout_]",
    [
      "",
      "This tries to connect to _socket-addr_. If a _connect-timeout_ is given, it",
      "will try to connect within that time. Please note that the returned sockets are",
      "thread safe and can be passed to another thread via an _Atom_, _Atom Value",
      "Slot_ or _Channel_ for instance.",
      "",
      "_socket-addr_ can be:",
      "",
      "- A pair `$p(host, port)`",
      "- A string like \"host:port\".",
      "- A pair within a pair to specify whether to use IPv4 or IPv6",
      "addresses only:",
      "    - `$p(:v4, \"host:port\")`",
      "    - `$p(:v4, $p(host, port))`",
      "    - `$p(:v6, \"host:port\")`",
      "    - `$p(:v6, $p(host, port))`",
      "",
      "About _connect-timeout_ see std:thread:sleep.",
      "",
      "```test",
      "!socket =",
      "    match (std:net:tcp:connect \"127.0.0.1:8328\")",
      "        ($e err) => { panic (\"Couldn't connect: \" + str[$\\.err]) }",
      "        socket   => $\\.socket;",
      "```",
      ""
    ]
  ],
  [
    "11.2.2 - std:net:tcp:listen _socket-addr_ _function_",
    [
      "",
      "Tries to bind a local port to _socket-addr_ (see std:net:tcp:connect about",
      "_socket-addr_.  Note: you can't use `$p(:v4 / :v6, ...)`).",
      "Returns an error if something bad happened.",
      "",
      "For every new connection _function_ is called with the socket",
      "as first argument:",
      "",
      "```text",
      "unwrap ~ std:net:tcp:listen \"0.0.0.0:8292\" {!(socket) = @;",
      "    std:io:write socket \"Hello!\\r\\n\";",
      "};",
      "```",
      "",
      "Please note that you can share the socket with other threads, see also `std:net:tcp:connect`.",
      ""
    ]
  ],
  [
    "11.2.3 - std:net:udp:new _socket-addr_ [_connect-addr_]",
    [
      "",
      "Creates a new UDP socket and binds it to an endpoint.  The arguments",
      "_socket-addr_ and _connect-addr_ have the same properties as the _socket-addr_",
      "that `std:net:tcp:connect` receives.",
      "",
      "If _connect-addr_ is given, a connected UDP port is created and",
      "`std:net:udp:send` does not need to pass a _socket-addr_.",
      "",
      "Returns a socket or an error.",
      "",
      "The socket can be shared between threads, so you can have a receiving",
      "thread and a sending one.",
      "",
      "```wlambda",
      "!socket = std:net:udp:new \"0.0.0.0:31889\";",
      "",
      "std:net:udp:send socket $b\"TEST\" \"127.0.0.1:31888\";",
      "```",
      "",
      "Here is a more elaborate example using threads:",
      "",
      "```wlambda",
      "!hdl = std:thread:spawn $code {",
      "    !socket = std:net:udp:new \"0.0.0.0:31889\";",
      "    _READY.send :ok;",
      "",
      "    !(data, addr) = std:net:udp:recv socket;",
      "    std:displayln \"PING\" data;",
      "    unwrap ~ std:net:udp:send socket (\"Test:\" data) addr;",
      "};",
      "",
      "hdl.recv_ready[];",
      "",
      "!socket = std:net:udp:new \"0.0.0.0:31888\" \"127.0.0.1:31889\";",
      "unwrap ~ std:net:udp:send socket $b\"XYB123\";",
      "",
      "!(data, addr) = unwrap ~ std:net:udp:recv socket;",
      "",
      "std:displayln \"PONG\" data;",
      "",
      "std:assert_eq data $b\"Test:XYB123\";",
      "",
      "hdl.join[];",
      "```",
      ""
    ]
  ],
  [
    "11.2.4 - std:net:udp:send _socket_ _data_ [_socket-addr_]",
    [
      "",
      "Sends the _data_ to the given _socket-addr_ or to the connected",
      "address of the _socket_.",
      "",
      "Returns the number of bytes sent or an error.",
      "",
      "```wlambda",
      "!socket = std:net:udp:new \"0.0.0.0:31889\";",
      "",
      "std:net:udp:send socket $b\"TEST\" \"127.0.0.1:31888\";",
      "```",
      ""
    ]
  ],
  [
    "11.2.5 - std:net:udp:recv _socket_ [_byte-count_]",
    [
      "",
      "Receives _byte-count_ number of bytes from the given _socket_.",
      "If _byte-count_ is omitted 512 is assumed.",
      "",
      "Returns the byte vector with the data and the endpoint address",
      "that it was received from. Or an error.",
      "",
      "```text",
      "!socket = std:net:udp:new \"0.0.0.0:31889\";",
      "",
      "!(buf, addr) = std:net:udp:recv socket;",
      "```",
      ""
    ]
  ],
  [
    "11.3 - Processes",
    [
      "",
      "This chapter documents how to execute new processes.",
      ""
    ]
  ],
  [
    "11.3.1 - std:process:run _executable-path_ [_arguments_]",
    [
      "",
      "Starts the given _executable-path_ with the given (but optional) _arguments_.",
      "_arguments_ can be a vector or an iterator. A data structure containing",
      "information about the finished child process or an error is returned if something",
      "went wrong.",
      "",
      "This function will block the current thread while the child process",
      "is executed. It collects the output of the child process and returns",
      "it in a data structure of the following form:",
      "",
      "```text",
      "{",
      "    status  = 0,        # exit code",
      "    success = $true,    # $true or $false",
      "    stdout  = $b\"...\",  # data printed to stdout",
      "    stderr  = $b\"...\",  # data printed to stderr",
      "}",
      "```",
      "",
      "Here is an example for Linux:",
      "",
      "```text",
      "!ret = unwrap ~ std:process:run \"sh\" $[\"-c\", \"echo \\\"test\\\"\"];",
      "",
      "std:assert_eq ret.status  0;",
      "std:assert_eq ret.success $true;",
      "std:assert_eq ret.stdout  $b\"test\\n\";",
      "std:assert_eq ret.stderr  $b\"\";",
      "```",
      ""
    ]
  ],
  [
    "11.3.2 - std:process:spawn _executable-path_ _arg-vector_ [:inherit_out | :inherit_all]",
    [
      "",
      "Like `std:process:run` starts a process from the _executable-path_ and _arg-vector_.",
      "But it does not wait until the process finished running, it returns a child process handle",
      "or an error if something went wrong.",
      "",
      "The handle can then be used by functions like:",
      "",
      "* `std:process:kill_wait` - to kill and wait for the process to exit",
      "* `std:process:try_wait` - to check if the process exited",
      "* `std:process:wait` - to wait until the process exits",
      "",
      "The third argument specifies what happens with the standard I/O file handles.",
      "By default the child process gets _null_ handles, so neither output is captured",
      "nor input is passed:",
      "",
      "* _default_ - child process gets _null_ handles for stdin, stdout and stderr.",
      "* `:inherit_out` - child process inherits stdout and stderr, but stdin will be _null_.",
      "* `:inherit_all` - child process inherits all (stdout, stderr and stdin) from the",
      "parent and uses them until it exits.",
      "",
      "TODO: Implement pipe to/from the child process to be",
      "read/written to via `std:io:read_some` and `std:io:write`.",
      "",
      "```wlambda",
      "!hdl = unwrap ~ std:process:spawn \"bash\" $[",
      "    \"-c\", \"for i in `seq 0 10`; do echo $i; sleep 0.2; done; exit 20\"",
      "];",
      "",
      "# do something in your program....",
      "",
      "!result = unwrap ~ std:process:wait hdl;",
      "",
      "std:assert ~ not result.success;",
      "std:assert result.status == 20;",
      "```",
      ""
    ]
  ],
  [
    "11.3.3 - std:process:try_wait _child-handle_",
    [
      "",
      "Checks if the child process behind _child-handle_ exited. Returns `$none` if",
      "it did not exit yet. Returns a map with the structure",
      "`${ status = ..., success = $true / $false }` if the child exited.",
      "Or an error if something failed.",
      "",
      "```wlambda",
      "!hdl = unwrap ~ std:process:spawn \"bash\" $[",
      "    \"-c\", \"for i in `seq 0 10`; do echo $i; sleep 0.2; done; exit 20\"",
      "];",
      "",
      "!counter = 0;",
      "!ret = $none;",
      "while $true {",
      "    std:thread:sleep :ms => 250;",
      "    .counter += 1;",
      "",
      "    .ret = unwrap ~ std:process:try_wait hdl;",
      "    if ret {",
      "        break ret;",
      "    };",
      "};",
      "",
      "std:assert counter > 0;",
      "std:assert ~ not ret.success;",
      "std:assert ret.status == 20;",
      "```",
      ""
    ]
  ],
  [
    "11.3.4 - std:process:kill_wait _child-handle_",
    [
      "",
      "Kills the child process behind _child-handle_ and waits for it to return the exit status.",
      "Returns a map with the structure `${ status = ..., success = $true / $false }` if the child exited.",
      "Or an error if something failed.",
      "",
      "```wlambda",
      "!hdl = unwrap ~ std:process:spawn \"bash\" $[",
      "    \"-c\", \"for i in `seq 0 10`; do echo $i; sleep 0.2; done; exit 20\"",
      "];",
      "",
      "!res = std:process:kill_wait hdl;",
      "",
      "std:assert ~ not res.success;",
      "std:assert_eq res.status -1;",
      "```",
      ""
    ]
  ],
  [
    "11.3.5 - std:process:wait _child-handle_",
    [
      "",
      "Waits until the child process behind _child-handle_ exits by itself.",
      "Returns a map with the structure `${ status = ..., success = $true / $false }`",
      "if the child exited. Or an error if something failed.",
      "",
      "```wlambda",
      "!hdl = unwrap ~ std:process:spawn \"bash\" $[",
      "    \"-c\", \"for i in `seq 0 10`; do echo $i; sleep 0.2; done; exit 20\"",
      "];",
      "",
      "!res = std:process:wait hdl;",
      "",
      "std:assert ~ not res.success;",
      "std:assert_eq res.status 20;",
      "```",
      ""
    ]
  ],
  [
    "11.4 - File System",
    [
      ""
    ]
  ],
  [
    "11.4.1 - std:fs:rename _file-path_ _new-file-name_",
    [
      "",
      "Renames the file at _file-path_ to the new name _new-file-name_. This",
      "usually does only work on a single file system.",
      "Returns `$true` if renaming was successful, and an error object if it was not",
      "successful.",
      ""
    ]
  ],
  [
    "11.4.2 - std:fs:copy _src-file-path_ _dst-file-path_",
    [
      "",
      "Copies the file _src-file-path_ to the _dst-file-path_.",
      "Returns an error if something went wrong.",
      ""
    ]
  ],
  [
    "11.4.3 - std:fs:read_dir _path_ _function_",
    [
      "",
      "Calls _function_ with the first argument being the directory entry as map",
      "of this structure:",
      "",
      "```wlambda",
      "    ${",
      "        atime     = 1587628635, # seconds since UNIX Epoch",
      "        ctime     = 1557382099, # seconds since UNIX Epoch",
      "        mtime     = 1557382099, # seconds since UNIX Epoch",
      "        len       = 478,        # bytes",
      "        name      = \"test\",     # file name",
      "        path      = \"..\\\\test\", # path name",
      "        read_only = $false,     # read only flag",
      "        type      = :f          # possible values:",
      "                                #   - :f for files",
      "                                #   - :l for symlinks",
      "                                #   - :d for directories",
      "    }",
      "```",
      "",
      "If the _function_ is called with a directory, you can recurse into that",
      "directory by returning a `$true` value.",
      "",
      "You can format the timestamps using `std:chrono:format_utc`.",
      ""
    ]
  ],
  [
    "11.4.4 - std:fs:remove_file _file-path_",
    [
      "",
      "Removes the file at the given _file-path_.",
      "Returns an error if the file is missing or some other error occured.",
      ""
    ]
  ],
  [
    "11.4.5 - std:fs:remove_dir _dir-path_",
    [
      "",
      "Removes the dir at the given _dir-path_.",
      "Returns an error if the dir is missing, is not empty",
      "or some other error occured.",
      ""
    ]
  ],
  [
    "11.4.6 - std:fs:remove_dir_all _dir-path_",
    [
      "",
      "Removes the given _dir-path_ recursively. Use with care!",
      "Returns an error if the directory does not exist.",
      ""
    ]
  ],
  [
    "11.5 - System",
    [
      "",
      "This chapter contains a few system as in _operating system_ related functions.",
      ""
    ]
  ],
  [
    "11.5.1 - std:sys:os",
    [
      "",
      "Returns the name of the operating system. These are some possible",
      "values:",
      "",
      "- linux",
      "- macos",
      "- ios",
      "- freebsd",
      "- dragonfly",
      "- netbsd",
      "- openbsd",
      "- solaris",
      "- android",
      "- windows",
      "",
      "```wlambda",
      "std:assert (len std:sys:os[]) > 0;",
      "```",
      ""
    ]
  ],
  [
    "11.6 - Threading",
    [
      "",
      "WLambda leverages the `std::thread` implementation of Rust's standard library",
      "to provide safe threading. Threading works by spawning new threads that",
      "get sent a piece of WLambda code (as string) and some arguments.",
      "",
      "Most WLambda data can be shared between threads. An exception are",
      "UserData values that are not thread safe. Also things like sharing",
      "cyclic data structures are not possible, as the references are currently",
      "broken up.",
      "",
      "Sharing data is done by WLambda by transforming the _VVal_ data structures",
      "into a thread safe shareable represenation called _AVal_. An AVal is a",
      "deep copy of the original VVal and can additionally contain atoms (see `std:sync:atom:new`),",
      "MPSC queues (see `std:sync:mpsc:new`) and value slots (see `std:sync:slot:new`).",
      "",
      "The scope of threading in WLambda is primarily to provide a way to do asynchronous",
      "work and not so much for high performance computing. You can of course enhance",
      "performance a bit with threading, but if you want to do heavy computing I recommend",
      "implementing your algorithm in Rust instead. You can of course still manage",
      "thread orchestration in WLambda if you just provide a simple function",
      "API to your algorithms.",
      ""
    ]
  ],
  [
    "11.6.1 - std:thread:spawn _string_ [_globals-map_]",
    [
      "",
      "This evaluates the given _string_ as WLambda code in a new thread.",
      "It returns a thread handle, that can be used to join the thread or",
      "wait for it to have properly started.",
      "",
      "The new thread starts out with a completely empty global environment.",
      "If you need any builtin functions, use `!@wlambda`, `!@import std`",
      "and other import statements to load the needed functions.",
      "",
      "If a _globals-map_ is given, inside the thread the given global",
      "variables will be set to the given value.",
      "",
      "Inside the thread, a global variable called `_READY` is set to",
      "an atomic slot, which can be used to signal the parent thread",
      "that the new thread has successfully spawned.",
      "",
      "This is a very basic example how to calculate something in",
      "a worker thread and wait in a blocking manner:",
      "",
      "```wlambda",
      "!handle = std:thread:spawn $code {",
      "    # Attention: Even if this example does not use any",
      "    #            built in functions, it's a good practice",
      "    #            to load them into the global environment",
      "    #            of the thread!",
      "    !@wlambda;",
      "    !@import std;",
      "",
      "    !sum = $@i iter i 0 => 10 {",
      "        $+ i;",
      "    };",
      "    _READY.send $[:ok, sum];",
      "",
      "    100",
      "};",
      "",
      "std:assert_str_eq handle.recv_ready[] $[:ok, 45];",
      "",
      "!res = handle.join[];",
      "",
      "std:assert_str_eq res 100;",
      "```",
      "",
      "Here an example on how to pass values to the thread.",
      "Please be aware, that only a limited set of data types can be",
      "passed to a thread. Functions and iterators can not be passed for",
      "instance.",
      "",
      "```wlambda",
      "!globals = ${",
      "    a = 99,",
      "    b = $[1, 3, 4],",
      "};",
      "",
      "!handle = std:thread:spawn $code {",
      "    a + b.1",
      "} globals;",
      "",
      "!res = handle.join[];",
      "",
      "std:assert_str_eq res 102;",
      "```",
      ""
    ]
  ],
  [
    "11.6.2 - std:thread:sleep _duration_",
    [
      "",
      "Lets the current thread sleep for the given _duration_.",
      "_duration_ can either be an integer that will be interpreted",
      "as milliseconds to sleep. Or a pair, containing the duration unit as first element",
      "and the integer as second element. Following units are supported:",
      "",
      "- `$p(:s, _seconds_)`",
      "- `$p(:ms, _milliseconds_)`",
      "- `$p(:us, _microseconds_)`",
      "- `$p(:ns, _nanoseconds_)`",
      "",
      "```wlambda",
      "!before = std:time:now :ms;",
      "!thrd = std:thread:spawn $code {",
      "    !@import std;",
      "    std:thread:sleep :ms => 150;",
      "};",
      "",
      "thrd.join[];",
      "",
      "!after = std:time:now :ms;",
      "",
      "std:assert (after - before) >= 150;",
      "```",
      ""
    ]
  ],
  [
    "11.6.3 - Thread Handle API",
    [
      ""
    ]
  ],
  [
    "11.6.3.1 - thdl.join",
    [
      "",
      "This method will wait for the thread to finish and return",
      "the return value of the thread.",
      "",
      "```wlambda",
      "!thdl = std:thread:spawn \"4 + 3\";",
      "std:assert_eq thdl.join[] 7;",
      "```",
      "",
      "This method will return an error if the thread handle was already joined.",
      ""
    ]
  ],
  [
    "11.6.3.2 - thdl.recv_ready",
    [
      "",
      "Waits for the global `_READY` atomic value slot to be sent a value by the",
      "thread. This is useful for waiting until the thread has started without an",
      "error before expecting it to run properly.",
      "If an error happens, you will receive an error object as return value of",
      "`recv_ready`:",
      "",
      "```wlambda",
      "!thdl = std:thread:spawn $code {",
      "    !@wlambda; # importing `panic`",
      "    panic \"SOME ERR\";",
      "    _READY.send :ok;",
      "};",
      "",
      "!err_msg =",
      "    match thdl.recv_ready[]",
      "        ($e err) => { $\\.err.0 }",
      "        v        => $\\.v;",
      "",
      "$DEBUG err_msg;",
      "std:assert err_msg &> $r/ *SOME\\ ERR* /;",
      "",
      "thdl.join[];",
      "```",
      "",
      "This method might return an error if the thread provider",
      "made a handle without a ready slot.",
      ""
    ]
  ],
  [
    "11.6.4 - Atom API",
    [
      "",
      "For threads a VVal (WLambda data value) is transformed into a value",
      "that can be shared between threads safely. For this the data values are cloned",
      "deeply and transformed into a structure of atomic values.",
      "",
      "These values are then stored in a so called _Atom_. They can be safely changed",
      "by threads.",
      ""
    ]
  ],
  [
    "11.6.4.1 - std:sync:atom:new _value_",
    [
      "",
      "Creates an Atom, containing the given _value_. The data types for _value_",
      "is limited to these:",
      "",
      "- Numbers (Integer, Float)",
      "- Numerical Vectors",
      "- Vectors",
      "- Maps",
      "- Strings",
      "- Symbols",
      "- Byte vectors",
      "- Pairs",
      "- Booleans",
      "- Optionals",
      "- Errors",
      "",
      "And also these special types:",
      "",
      "- Atom",
      "- Atom Value Slot",
      "- Channel",
      "",
      "```wlambda",
      "!at = std:sync:atom:new $[1, 2, 3];",
      "",
      "!thdl = std:thread:spawn $code {",
      "    at.write ~ $@i iter i at.read[] {",
      "        $+ i;",
      "    };",
      "    _READY.send :ok;",
      "} ${ at = at };",
      "",
      "thdl.recv_ready[];",
      "",
      "std:assert_eq at.read[] 6;",
      "",
      "thdl.join[]",
      "```",
      ""
    ]
  ],
  [
    "11.6.4.2 - atom.read",
    [
      "",
      "Returns the value stored in the atom.",
      "",
      "```wlambda",
      "!at = std:sync:atom:new 99;",
      "",
      "std:assert_eq at.read[] 99;",
      "```",
      "",
      "This method might return an error if the internal mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.4.3 - atom.write _value_",
    [
      "",
      "Overwrites the contents of the atom with the given _value_.",
      "",
      "```wlambda",
      "!at = std:sync:atom:new 99;",
      "",
      "at.write 100;",
      "",
      "std:assert_eq at.read[] 100;",
      "```",
      "",
      "This method might return an error if the internal mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.4.4 - atom.swap _value_",
    [
      "",
      "Returns the previous value of the atom and writes in",
      "the given _value_.",
      "",
      "```wlambda",
      "!at = std:sync:atom:new 99;",
      "",
      "std:assert_eq at.swap[100] 99;",
      "",
      "std:assert_eq at.read[] 100;",
      "```",
      "",
      "This method might return an error if the internal mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5 - Atom Value Slot API",
    [
      "",
      "An Atom value slot offers more synchronization than a normal Atom value.",
      "It allows you to set the value of the slot, wait for it to be collected",
      "and wait for a value becoming available.",
      "It can be thought of a single element queue, where the element will be",
      "overwritten when a new value is sent to the slot.",
      "",
      "You can theoretically receive or wait from multiple threads and also write from",
      "multiple threads. But be aware, that the order of which threads get to read or",
      "write is determined by the operating system and might lead to reader or writer",
      "starvation.",
      "",
      "Best recommendation here is to use a slot only from a single writer and",
      "a single reader.",
      ""
    ]
  ],
  [
    "11.6.5.1 - std:sync:slot:new",
    [
      "",
      "Constructs a new Atom slot and returns it.",
      "The slot has the initial status of being _empty_.",
      "If a value is sent to it, it will not be _empty_ anymore.",
      "After a value is received from the slot, the status is _empty_ again.",
      ""
    ]
  ],
  [
    "11.6.5.2 - atom_slot.send _value_",
    [
      "",
      "This method sends the value into the slot, overwriting any previous",
      "set values. The slot can also ha",
      "",
      "```wlambda",
      "!slot = std:sync:slot:new[];",
      "",
      "std:assert slot.check_empty[];",
      "",
      "slot.send $[:ok, $i(1,2,3)];",
      "",
      "std:assert ~ not slot.check_empty[];",
      "",
      "std:assert_eq slot.recv[].1 $i(1,2,3);",
      "",
      "std:assert slot.check_empty[];",
      "```",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.3 - atom_slot.recv",
    [
      "",
      "If the slot is empty, it will wait for a value to become available.",
      "Once a value is available it is returned and the slot is set to _empty_ again.",
      "",
      "```wlambda",
      "!slot = std:sync:slot:new[];",
      "",
      "!thrd = std:thread:spawn $code {",
      "    slot.send 99;",
      "} ${ slot = slot };",
      "",
      "std:assert_eq slot.recv[] 99;",
      "",
      "thrd.join[];",
      "```",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.4 - atom_slot.try_recv",
    [
      "",
      "This method returns an optional value. It will provide an empty optional",
      "value if no value is stored in the slot. But if the slot contains",
      "a value, it will return the value (wrapped in an optional) and set the",
      "slot to be _empty_ again.",
      "",
      "```wlambda",
      "!slot       = std:sync:slot:new[];",
      "!start_flag = std:sync:slot:new[];",
      "",
      "!thrd = std:thread:spawn $code {",
      "",
      "    start_flag.recv[]; # sync with parent",
      "",
      "    slot.send 99;",
      "",
      "    _READY.send :ok;",
      "",
      "} ${ slot = slot, start_flag = start_flag };",
      "",
      "std:assert_eq slot.try_recv[] $o();",
      "",
      "start_flag.send :ok;",
      "thrd.recv_ready[];",
      "",
      "std:assert_eq slot.try_recv[] $o(99);",
      "",
      "thrd.join[];",
      "```",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.5 - atom_slot.recv_timeout _duration_",
    [
      "",
      "Acts like `atom_slot.recv`, but it will only wait for the given _duration_.  If",
      "no value was received in the given _duration_ (see std:thread:sleep), `$o()` is",
      "returned.  Otherwise the optional value will contain the received value.",
      "",
      "```wlambda",
      "!slot = std:sync:slot:new[];",
      "",
      "std:assert_eq (slot.recv_timeout :ms => 100) $o();",
      "",
      "slot.send 4;",
      "",
      "std:assert_eq (slot.recv_timeout :ms => 100) $o(4);",
      "```",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.6 - atom_slot.check_empty",
    [
      "",
      "Returns `$true` if the slot is empty.",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.7 - atom_slot.wait_empty",
    [
      "",
      "Waits until the slot is empty and then returns `$true`.",
      "",
      "This method might return an error if there was an issue with locking",
      "the internal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.5.8 - atom_slot.wait_empty_timeout _duration_",
    [
      "",
      "Waits a predefined timeout until the slot is empty. If it did become",
      "empty within the given _duration_ (see std:thread:sleep) it will return `$true`.",
      "Otherwise it will return `$false`.",
      "",
      "This method might return an error if there was an issue with locking",
      "the interal mutex or the mutex was poisoned.",
      ""
    ]
  ],
  [
    "11.6.6 - Channel API",
    [
      "",
      "A channel is a multiple sender, single consumer queue. It can be used to",
      "establish a message passing based communication between threads.",
      "",
      "It is basically a wrapper around the Rust `std::sync::mpsc::channel`.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "!thdl = std:thread:spawn $code {",
      "    _READY.send :ok;",
      "    iter i 0 => 10 {",
      "        chan.send $p(:val, i);",
      "    };",
      "    chan.send $p(:quit, $none);",
      "} ${ chan = chan };",
      "",
      "match thdl.recv_ready[]",
      "    ($e ?) => { std:assert $false };",
      "",
      "!item = $none;",
      "",
      "!sum = $@i",
      "    while { .item = chan.recv[]; item.0 == :val } {",
      "        $+ item.1;",
      "    };",
      "",
      "std:assert_eq sum 45;",
      "",
      "thdl.join[];",
      "```",
      ""
    ]
  ],
  [
    "11.6.6.1 - std:sync:mpsc:new",
    [
      "",
      "This creates a new channel. You can safely send from multiple threads",
      "while reading from one thread at a time.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "chan.send :a;",
      "chan.send :b;",
      "chan.send :c;",
      "",
      "std:assert_eq chan.recv[] :a;",
      "std:assert_eq chan.recv[] :b;",
      "std:assert_eq chan.recv[] :c;",
      "```",
      ""
    ]
  ],
  [
    "11.6.6.2 - channel.send _value_",
    [
      "",
      "Sends the given _value_ to the channel queue.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "chan.send :a;",
      "std:assert_eq chan.recv[] :a;",
      "```",
      "",
      "This method might return an error if the channel failed, for instance due",
      "to a poisoned internal mutex.",
      ""
    ]
  ],
  [
    "11.6.6.3 - channel.recv",
    [
      "",
      "Receives the next element from the channel. If no element is available",
      "this method will block the thread until an element becomes available.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "chan.send :a;",
      "std:assert_eq chan.recv[] :a;",
      "```",
      "",
      "This method might return an error if the channel failed, for instance due",
      "to a poisoned internal mutex.",
      ""
    ]
  ],
  [
    "11.6.6.4 - channel.try_recv",
    [
      "",
      "Tries to receive the next element from the channel and return it wrapped",
      "into an optional. If no element is available an empty optional `$o()` is returned.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "std:assert_eq chan.try_recv[] $o();",
      "",
      "chan.send :a;",
      "",
      "std:assert_eq chan.try_recv[] $o(:a);",
      "```",
      "",
      "This method might return an error if the channel failed, for instance due",
      "to a poisoned internal mutex.",
      ""
    ]
  ],
  [
    "11.6.6.5 - channel.recv_timeout _duration_",
    [
      "",
      "Tries to receive the next element in the given _duration_ (see std:thread:sleep)",
      "and return it wrapped into an optional. If no element could be received",
      "within that time an empty optional is returned `$o()`.",
      "",
      "```wlambda",
      "!chan = std:sync:mpsc:new[];",
      "",
      "std:assert_eq (chan.recv_timeout $p(:ms, 100)) $o();",
      "",
      "chan.send :x;",
      "",
      "std:assert_eq (chan.recv_timeout $p(:ms, 100)) $o(:x);",
      "```",
      "",
      "This method might return an error if the channel failed, for instance due",
      "to a poisoned internal mutex.",
      ""
    ]
  ],
  [
    "12 - Optional Standard Library",
    [
      ""
    ]
  ],
  [
    "12.1 - serialization",
    [
      ""
    ]
  ],
  [
    "12.1.1 - std:ser:wlambda _arg_",
    [
      "",
      "Returns the serialized WLambda representation of the value _arg_ as string.",
      "",
      "Most values have the same represenation like a WLambda literal,",
      "but there are other values that don't have a literal representation.",
      "",
      "Warning: Consider all values that don't have a fixed literal representation",
      "in the WLambda syntax as debug output that might change in future versions.",
      "",
      "```wlambda",
      "std:assert_eq (std:ser:wlambda \"foo\") $q|\"foo\"|;",
      "std:assert_eq (std:ser:wlambda $none) $q|$n|;",
      "std:assert_eq (std:ser:wlambda $[1,:a]) $q|$[1,:a]|;",
      "```",
      ""
    ]
  ],
  [
    "12.1.2 - std:ser:json _data_ \\[_no_pretty_]",
    [
      "",
      "Serializes the _data_ and returns a JSON formatted (and pretty printed) string.",
      "Optionally not pretty printed if _no_pretty_ is a true value.",
      "",
      "```wlambda",
      "!str = std:ser:json $[1,2.3,${a=4}] $t;",
      "std:assert_eq str \"[1,2.3,{\\\"a\\\":4}]\";",
      "```",
      ""
    ]
  ],
  [
    "12.1.3 - std:deser:json _string_",
    [
      "",
      "Deserializes the JSON formatted _string_ into a data structure.",
      "",
      "```wlambda",
      "!data = std:deser:json ~ std:ser:json $[1,2.3,${a=4}];",
      "std:assert_eq data.0 1;",
      "std:assert_eq data.1 2.3;",
      "std:assert_eq data.(2).a 4;",
      "```",
      ""
    ]
  ],
  [
    "12.1.4 - std:ser:csv _field_delim_ _row_separator_ _escape_all_ _table_",
    [
      "",
      "This serializes the _table_ as CSV with the given _field_delim_",
      "and _row_separator_. If _escape_all_ is `$true` all fields will be",
      "put into '\"'.",
      "",
      "```wlambda",
      "!csv_str =",
      "    std:ser:csv",
      "        \";\" \"|\" $f",
      "        $[ $[1,2,3,4,$q/foo\"bar/],",
      "           $[44,55],",
      "           $[]]",
      "    | std:displayln;",
      "",
      "std:assert_eq csv_str $q/1;2;3;4;\"foo\"\"bar\"|44;55||/;",
      "",
      "std:assert_eq",
      "    (std:ser:csv \";\" \"|\" $f $[$[:a,$q/;/, $q/|/, $q/ /]])",
      "    \"a;\\\";\\\";\\\"|\\\";\\\" \\\"|\";",
      "```",
      ""
    ]
  ],
  [
    "12.1.5 - std:deser:csv _field_delim_ _row_separator_ _data_",
    [
      "",
      "Parses the string _data_ as CSV. With the field delimiter _field_delim_",
      "and the _row_separator_ for the data rows.",
      "",
      "```wlambda",
      "!table = std:deser:csv \";\" \"\\r\\n\" \"foo;bar\\r\\nx;y\\r\\n\";",
      "std:assert_eq table.0.0 \"foo\";",
      "std:assert_eq table.0.1 \"bar\";",
      "std:assert_eq table.1.1 \"y\";",
      "```",
      ""
    ]
  ],
  [
    "12.1.6 - std:ser:msgpack _data_",
    [
      "",
      "Serializes the _data_ and returns a msgpack bytes value.",
      "",
      "```wlambda",
      "std:assert_eq (std:ser:msgpack $b\"abc\") $b\"\\xC4\\x03abc\";",
      "```",
      ""
    ]
  ],
  [
    "12.1.7 - std:deser:msgpack _bytes_",
    [
      "",
      "Deserializes the msgpack bytes value into a data structure.",
      "",
      "```wlambda",
      "std:assert_eq (std:deser:msgpack $b\"\\xC4\\x03abc\") $b\"abc\";",
      "```",
      ""
    ]
  ],
  [
    "12.2 - Regular Expressions (more classic syntax)",
    [
      "",
      "WLambda supports a more common form of regular expression syntax",
      "if the \"regex\" feature is enabled when compiling WLambda.",
      "",
      "It uses the regex syntax as described in the Rust \"regex\" crate:",
      "[https://docs.rs/regex/newest/regex/](https://docs.rs/regex/newest/regex/#syntax).",
      ""
    ]
  ],
  [
    "12.2.1 - std:re:match _regex-string_ _input-string_ _function_",
    [
      "",
      "If the given regular expression _regex-string_ matches the given _input-string_",
      "the _function_ will be called with a vector containing the matched string",
      "and the captures as first argument.",
      "The return value is the return value of the function call or `$none`.",
      "Returns an error if the _regex-string_ has a syntax error.",
      "",
      "```wlambda",
      "!ret = std:re:match $q|(\\d+)-(\\d+)-(\\d+)| \"2020-05-01\" {",
      "    std:str:join \".\" std:reverse <& (1 => 3) <&_;",
      "};",
      "",
      "std:assert_str_eq ret \"01.05.2020\";",
      "```",
      ""
    ]
  ],
  [
    "12.2.2 - std:re:match_compile _regex-string_",
    [
      "",
      "This function compiles the given _regex-string_ and returns a function that",
      "will execute the regex matching. If the syntax in _regex-string_ is wrong,",
      "an error is returned.",
      "",
      "The returned function takes the string to match against as first parameter",
      "and the function that is called if the regex matches as second parameter.",
      "",
      "```wlambda",
      "!match_fun = std:re:match_compile $q|(\\d+)-(\\d+)-(\\d+)|;",
      "",
      "!ret = match_fun \"2020-05-01\" {",
      "    std:str:join \".\" std:reverse <& (1 => 3) <&_;",
      "};",
      "",
      "std:assert_str_eq ret \"01.05.2020\";",
      "```",
      ""
    ]
  ],
  [
    "12.2.3 - std:re:map _regex-string_ _function_ _input-string_",
    [
      "",
      "Executes _function_ for each match of the regex defined by _regex-string_",
      "on the _input-string_. Returns an error if there is a syntax error in the regex.",
      "Otherwise returns the last return value of _function_.",
      "",
      "```wlambda",
      "!res = $@vec std:re:map $q|(\\d+)-(\\d+)-(\\d+)| {!(str, d1, d2, d3) = _;",
      "    $+ $[int d1, int d2, int d3]",
      "} \"foo bar 2020-05-01 fofo 2020-06-01 bar 2019-12-31\";",
      "",
      "std:assert_str_eq res $[$[2020,5,1], $[2020,6,1], $[2019,12,31]];",
      "```",
      ""
    ]
  ],
  [
    "12.2.4 - std:re:replace_all _regex-string_ _replace-function_ _input-string_",
    [
      "",
      "This function replaces all matches of the regex _regex-string_ in the _input-string_",
      "by the return value of the _replace-function_. Returns an error if there is",
      "a syntax error in the _regex-string_.",
      "",
      "```wlambda",
      "!res = std:re:replace_all $q\"(\\d+)\" {",
      "    str (int _.1) + 1",
      "} \"foo 32 fifi 99\";",
      "",
      "std:assert_eq res \"foo 33 fifi 100\";",
      "```",
      ""
    ]
  ],
  [
    "12.3 - xml",
    [
      ""
    ]
  ],
  [
    "12.3.1 - std:xml:read_sax _xml-string_ _event-callback-function_ [_do-not-trim-text_]",
    [
      "",
      "```wlambda",
      "\\:x {",
      "    $@v _? :x ~ std:xml:read_sax",
      "        \"x<x a='12'>fooo fweor weio ew <i/> foefoe</i></x>y\"",
      "        $+;",
      "}[]",
      "```",
      ""
    ]
  ],
  [
    "12.3.2 - std:xml:create_sax_writer [_indent_]",
    [
      "",
      "Creates an XML SAX event based writer function. The function",
      "should be called with single events as received by `std:xml:read_sax`.",
      "To receive the final output of the writer, call the returned function",
      "without any arguments.",
      "",
      "```wlambda",
      "!writer = std:xml:create_sax_writer[];",
      "writer $[:start, \"test\"];",
      "writer $[:end, \"test\"];",
      "",
      "std:assert_eq writer[] \"<test></test>\";",
      "```",
      ""
    ]
  ],
  [
    "12.3.3 - std:xml:create_tree_builder",
    [
      "",
      "This function returns a function that acts as WLambda data structure builder",
      "that accepts SAX events as given to the callback of `std:xml:read_sax`.",
      "",
      "The returned data structure is a tree build of the following elements:",
      "",
      "- `$[:decl,    ${ version=..., encoding=..., standalone=... }]`",
      "- `$[:elem,    name, ${ <attributes> }, $[ <child elements> ]]`",
      "- `$[:comment, text]`",
      "- `$[:pi,      text]`",
      "- `$[:text,    text]`",
      "- `$[:doctype, text]`",
      "- `$[:cdata,   text]`",
      "",
      "Here is a more elaborate example on how to use it:",
      "",
      "```wlambda",
      "!tb = std:xml:create_tree_builder[];",
      "",
      "!tree = std:xml:read_sax $q$",
      "    <foo>",
      "        <i x=\"here\"/>",
      "        hello",
      "    </foo>",
      "    <foo>",
      "        blop<i x=\"10\"/>",
      "        lol",
      "    </foo>$",
      "    tb;",
      "",
      "std:assert_str_eq",
      "    tree",
      "    $[:root,$n,$n,$[",
      "        $[:elem,\"foo\",$n,$[",
      "            $[:elem,\"i\",${x=\"here\"},$n],$[:text,\"hello\"]]],",
      "        $[:elem,\"foo\",$n,$[",
      "            $[:text,\"blop\"],$[:elem,\"i\",${x=\"10\"},$n],$[:text,\"lol\"]]]",
      "    ]];",
      "",
      "# Here we use the structure matchers for finding the values of the x attributes",
      "# of the <i> elements:",
      "std:assert_str_eq",
      "    $S[ 3 / *:{0=elem,1=foo} /",
      "        3 / *:{0=elem,1=i} /",
      "        2 / x",
      "    ] <& tree",
      "    $[\"here\",\"10\"];",
      "```",
      ""
    ]
  ],
  [
    "12.4 - chrono",
    [
      ""
    ]
  ],
  [
    "12.4.1 - std:chrono:timestamp \\[_format_]",
    [
      "",
      "For the documentation of _format_ please consule the",
      "chrono Rust crate documentation: [chrono crate strftime format](https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers).",
      "",
      "```wlambda",
      "!year_str = std:chrono:timestamp \"%Y\";",
      "std:displayln :XXXX ~ (year_str | int) == 2022;",
      "std:assert ~ (year_str | int) == 2022;",
      "",
      "!now_str = std:chrono:timestamp[];",
      "```",
      ""
    ]
  ],
  [
    "12.4.2 - std:chrono:format_utc _utc-timestamp_ [_format_]",
    [
      "",
      "Formats the given _utc-timestamp_ in seconds according to _format_.",
      "",
      "For the documentation of _format_ please consule the",
      "chrono Rust crate documentation: [chrono crate strftime format](https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers).",
      "",
      "```wlambda",
      "!year_str = std:chrono:format_utc 1603796989 \"%H:%M:%S %Y\";",
      "",
      "std:assert_str_eq year_str \"11:09:49 2020\";",
      "```",
      ""
    ]
  ],
  [
    "12.4.3 - std:chrono:format_local _utc-timestamp_ [_format_]",
    [
      "",
      "Formats the given _utc-timestamp_ in seconds according to _format_ in the local timezone.",
      "",
      "For the documentation of _format_ please consule the",
      "chrono Rust crate documentation: [chrono crate strftime format](https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers).",
      "",
      "```wlambda",
      "!year_str = std:chrono:format_local 1603796989 \"%H:%M:%S %Y\";",
      "",
      "std:assert_str_eq year_str \"12:09:49 2020\";",
      "```",
      ""
    ]
  ],
  [
    "12.5 - color conversion",
    [
      "",
      "This section highlights the color conversion functions available in WLambda.",
      "Numerical vectors are used in WLambda to represent colors. There are two",
      "representations of a color.",
      "",
      "If you use a float vector `$f(r, g, b, a)` the values for RGB are in the range",
      "of 0.0 to 1.0. For HSV `$f(h, s, v, a)` h is within 0.0 to 360.0 while the",
      "others are in the range 0.0 to 1.0.",
      "",
      "For integer vectors the values for RGB are in the range 0 to 255.",
      "And the values for HSV are in the range 0 to 360, and the others in the range",
      "0 to 100.",
      "",
      "You can also use 3 dimensional vectors without the alpha value: `$i(r, g, b)` / `$i(h, s, v)`",
      "and `$f(r, g, b)` / `$f(h, s, v)`.",
      ""
    ]
  ],
  [
    "12.5.1 - std:v:rgb2hsv _color-vector_",
    [
      "",
      "Converts an RGB color into a HSV color representation.",
      "",
      "```wlambda",
      "std:assert_eq std:v:rgb2hsv <& $i(0, 255, 0, 255)   $i(120, 100, 100, 100);",
      "std:assert_eq std:v:rgb2hsv <& $i(0, 255, 0)        $i(120, 100, 100);",
      "",
      "std:assert_eq std:v:rgb2hsv <& $f(0, 1.0, 0, 1.0)   $f(120, 1, 1, 1);",
      "std:assert_eq std:v:rgb2hsv <& $f(0, 1.0, 0)        $f(120, 1, 1);",
      "",
      "std:assert_eq std:v:rgb2hsv <& $f(0, 0.5, 0, 1.0)     $f(120, 1, 0.5, 1);",
      "std:assert_eq std:v:rgb2hsv <& $f(0.1, 0.5, 0.1, 1.0) $f(120, 0.8, 0.5, 1);",
      "```",
      ""
    ]
  ],
  [
    "12.5.2 - std:v:hsv2rgb _color-vector_",
    [
      "",
      "Converts a color from HSV to RGB representation.",
      "",
      "```wlambda",
      "std:assert_eq std:v:hsv2rgb <& $i(120, 80, 50, 100)   $i(25,128,25,255);",
      "",
      "!clr = std:v:hsv2rgb <& $f(120, 0.8, 0.5, 1.0);",
      "std:assert_rel_eq clr.r 0.1 0.001;",
      "std:assert_rel_eq clr.g 0.5 0.001;",
      "std:assert_rel_eq clr.b 0.1 0.001;",
      "```",
      ""
    ]
  ],
  [
    "12.5.3 - std:v:rgba2hex _color-vector_",
    [
      "",
      "This function converts a color to a string of hex digits (without the common '#'",
      "prefix however).",
      "",
      "```wlambda",
      "std:assert_eq std:v:rgba2hex <& $i(255, 128, 64, 32)       \"ff804020\";",
      "std:assert_eq std:v:rgba2hex <& $f(1.0, 0.5, 0.25, 0.125)  \"ff804020\";",
      "```",
      ""
    ]
  ],
  [
    "12.5.4 - std:v:hex2rgba_f _string_",
    [
      "",
      "Interprets _string_ as an hex encoded color and",
      "returns a 4 element big float vector. The color components",
      "of the float vector go from 0.0 to 1.0.",
      "",
      "The string can be:",
      "",
      "- 8 characters: `\"RRGGBBAA\"`",
      "- 6 characters: `\"RRGGBB\"`, alpha will be 1.0",
      "- 4 characters: `\"RGBA\"`",
      "- 3 characters: `\"RGB\"`, alpha will be 1.0",
      "- 2 characters: `\"YY\"`, where YY is put into R, G and B. Alpha will be 1.0.",
      "",
      "```wlambda",
      "!color = std:v:hex2rgba_f \"FF00FFFF\";",
      "",
      "std:assert_rel_eq color.r 1.0 0.001;",
      "std:assert_rel_eq color.g 0.0 0.001;",
      "std:assert_rel_eq color.b 1.0 0.001;",
      "std:assert_rel_eq color.a 1.0 0.001;",
      "",
      "!color2 = std:v:hex2rgba_f \"C83F\";",
      "std:assert_rel_eq color2.r 0.8   0.001;",
      "std:assert_rel_eq color2.g 0.533 0.001;",
      "std:assert_rel_eq color2.b 0.2   0.001;",
      "std:assert_rel_eq color2.a 1.0   0.001;",
      "```",
      ""
    ]
  ],
  [
    "12.5.5 - std:v:hex2rgba_i _string_",
    [
      "",
      "Like `std:v:hex2rgba_f` this function converts a hex encoded color",
      "from _string_ but returns an integer vector with 4 elements.",
      "The integers are in the range of 0 to 255.",
      "",
      "About the format of _string_ please refer to `std:v:hex2rgba_f`.",
      "",
      "```wlambda",
      "!color = std:v:hex2rgba_i \"FF00FFFF\";",
      "",
      "std:assert_eq color.r 255;",
      "std:assert_eq color.g 0;",
      "std:assert_eq color.b 255;",
      "std:assert_eq color.a 255;",
      "",
      "!color2 = std:v:hex2rgba_i \"C83F\";",
      "std:assert_eq color2.r 204;",
      "std:assert_eq color2.g 136;",
      "std:assert_eq color2.b 51;",
      "std:assert_eq color2.a 255;",
      "```",
      ""
    ]
  ],
  [
    "12.5.6 - std:v:hex2hsva_i _string_",
    [
      "",
      "Converts the hex represenation of a HSVA color to an integer vector `$i(h, s, v, a)`.",
      "This function is probably not that useful, as the bit distribution along",
      "the 3 bytes is not ideal. If you want to store colors properly, don't use this.",
      "It's mostly useful for testing and quick experiments.",
      "",
      "```wlambda",
      "!color = std:v:hex2hsva_i \"FF8040FF\";",
      "std:assert_eq color $i(360,50,25,100);",
      "```",
      ""
    ]
  ],
  [
    "12.5.7 - std:v:hex2hsva_f _string_",
    [
      "",
      "Converts the hex represenation of a HSVA color to a float vector `$i(h, s, v, a)`.",
      "This function is probably not that useful, as the bit distribution along",
      "the 3 bytes is not ideal. If you want to store colors properly, don't use this.",
      "It's mostly useful for testing and quick experiments.",
      "",
      "```wlambda",
      "!color = std:v:hex2hsva_f \"FF8040FF\";",
      "",
      "std:assert_rel_eq color.0 360.0 1.0;",
      "std:assert_rel_eq color.1  50.0 1.0;",
      "std:assert_rel_eq color.2  25.0 1.0;",
      "std:assert_rel_eq color.3 100.0 1.0;",
      "```",
      ""
    ]
  ],
  [
    "12.6 - hash",
    [
      ""
    ]
  ],
  [
    "12.6.1 - std:hash:fnv1a _arg1_ ...",
    [
      "",
      "Hashes all the arguments as FNV1a and returns an integer.",
      ""
    ]
  ],
  [
    "12.7 - rand",
    [
      ""
    ]
  ],
  [
    "12.7.1 - std:rand:split_mix64_new",
    [
      "",
      "Initializes the _sm_state_ from the current time (seconds) and returns it.",
      "The time is retrieved in seconds, so don't expect different seed states",
      "if you call this multiple times in the same wall clock second.",
      "The returned value is supposed to be passed to `rand:split_mix64_next`",
      "or `rand:split_mix64_next_open01`.",
      ""
    ]
  ],
  [
    "12.7.2 - std:rand:split_mix64_new_from _seed_",
    [
      "",
      "Initializes the _sm_state_ from the given _seed_ and returns it.",
      "The returned value is supposed to be passed to `rand:split_mix64_next`",
      "or `rand:split_mix64_next_open01`.",
      ""
    ]
  ],
  [
    "12.7.3 - std:rand:split_mix64_next _sm_state_ \\[_count_]",
    [
      "",
      "Returns the _count_ next integer values generated from the given",
      "_sm_state_.",
      ""
    ]
  ],
  [
    "12.7.4 - std:rand:split_mix64_next_open01 _sm_state_ \\[_count_]",
    [
      "",
      "Returns the _count_ next float values (in an open [0, 1) interval)",
      "generated from the given _sm_state_.",
      ""
    ]
  ],
  [
    "12.7.5 - std:rand:split_mix64_next_open_closed01 _sm_state_ \\[_count_]",
    [
      "",
      "Returns the _count_ next float values (in an open (0, 1] interval)",
      "generated from the given _sm_state_.",
      ""
    ]
  ],
  [
    "12.7.6 - std:rand:split_mix64_next_closed_open01 _sm_state_ \\[_count_]",
    [
      "",
      "Returns the _count_ next float values (in an open [0, 1) interval)",
      "generated from the given _sm_state_.",
      ""
    ]
  ],
  [
    "12.8 - Utility Functions",
    [
      ""
    ]
  ],
  [
    "12.8.1 - std:dump_upvals _function_",
    [
      "",
      "Returns a vector of all the upvalues of the _function_.",
      "Please use this function for debugging purposes only, as the order of the",
      "variables, while consistent for a specific WLambda version,",
      "is not defined at this point.",
      "",
      "```wlambda",
      "!x = 1;",
      "!y = 2;",
      "!fun = { _ + x + y };",
      "",
      "std:assert_eq fun[3]   6;",
      ".x = 3;",
      "std:assert_eq fun[3]   8;",
      "",
      "!upvs = std:dump_upvals fun;",
      "std:assert_eq (str upvs) \"$[$&3,$&2]\";",
      ".y = 4;",
      "std:assert_eq (str upvs) \"$[$&3,$&4]\";",
      "",
      "std:assert_eq $*(upvs.0) 3;",
      "std:assert_eq $*(upvs.1) 4;",
      "```",
      ""
    ]
  ],
  [
    "12.8.2 - std:wlambda:version",
    [
      "",
      "Returns the version number of the WLambda crate when called.",
      ""
    ]
  ],
  [
    "12.8.3 - std:wlambda:sizes",
    [
      "",
      "Writes a table of internal data structure sizes to stdout. Just for development",
      "purposes.",
      ""
    ]
  ],
  [
    "12.8.4 - std:wlambda:parse _string_",
    [
      "",
      "Parses _string_ as if it was a piece of WLambda code and returns an abstract syntax tree.",
      "",
      "```wlambda",
      "std:assert_str_eq",
      "    (std:wlambda:parse \"1 + 2\")",
      "    $[$%:Block,$[$%:BinOpAdd,1,2]]",
      "```",
      ""
    ]
  ],
  [
    "12.9 - HTTP Client",
    [
      "",
      "WLambda offers an optional integrated HTTP client by enabling the `reqwest`",
      "feature at compile time. With this you can create a new client using `std:http:client:new` and make HTTP requests using `std:http:get`, `std:http:post` and `std:http:request`. Also support for basic authentication and token based bearer authentication",
      "is there.",
      ""
    ]
  ],
  [
    "12.9.1 - std:http:client:new",
    [
      "",
      "Creates a new HTTP client instance and returns it. You can use it to make",
      "HTTP requests afterwards.",
      "",
      "```wlambda",
      "!client = std:http:client:new[];",
      "!response = std:http:get client \"https://duckduckgo.com/\";",
      "",
      "!body = std:str:from_utf8_lossy response.body;",
      "std:assert ($p(0, \"</html>\") body) > 0;",
      "std:assert_eq response.status 200;",
      "std:assert_eq response.headers.content-type \"text/html; charset=UTF-8\";",
      "```",
      "",
      "See also `std:http:get` for a more elaborate example with providing headers.",
      ""
    ]
  ],
  [
    "12.9.2 - std:http:get _http-client_ _url-string_ [_headers-and-options-map_]",
    [
      "",
      "Performs a HTTP GET request to the given _url-string_ using the _http-client_.",
      "The _headers-and-options-map_ can contain following special keys apart from your",
      "custom HTTP headers themself:",
      "",
      "- `@basic_auth` with `$[user, $none]` or `$[user, password]` as value.",
      "- `@bearer_auth` with `token` as value.",
      "- `@timeout` with a timeout duration as value. (See also `std:thread:sleep`).",
      "- `@query` with a map of query parameters and their values to modify the",
      "query string of the _url-string_. This properly encodes the strings.",
      "",
      "The client will either return an error or a response map with following keys:",
      "",
      "- `status` contains the HTTP response code (usually `200` if everything went fine).",
      "- `reason` contains a human readable canonical reason string for the status.",
      "- `body` contains the byte vector with the body data.",
      "- `headers` contains a map of all headers, where the keys are the lower case",
      "header names.",
      "",
      "Here is an example on how to use this while providing HTTP Headers:",
      "",
      "```wlambda",
      "!client = std:http:client:new[];",
      "!response =",
      "    std:http:get client \"https://crates.io/api/v1/crates?page=1&per_page=10&q=wlambda\" ${",
      "        Accept        = \"application/json\",",
      "        Cache-Control = \"no-cache\",",
      "        DNT           = 1,",
      "        User-Agent    = \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0\",",
      "    };",
      "",
      "!body = std:deser:json ~ std:str:from_utf8_lossy response.body;",
      "# std:displayln ~ std:ser:json body $f;",
      "std:assert_eq body.crates.0.name            \"wlambda\";",
      "std:assert_eq response.headers.content-type \"application/json; charset=utf-8\";",
      "std:assert_eq response.status               200;",
      "```",
      ""
    ]
  ],
  [
    "12.9.3 - std:http:post _http-client_ _url-string_ _body-bytes_ [_headers-and-options-map_]",
    [
      "",
      "This call is like `std:http:get` but makes a HTTP POST request with the given payload _body_. For HTTP requests with other methods please look at `std:http:request`. The rest of the options are the same as `std:http:get`. But here is an example how to",
      "transmit a piece of JSON easily:",
      "",
      "```wlambda",
      "!client = std:http:client:new[];",
      "!response =",
      "    std:http:post client \"http://httpbin.org/post\"",
      "        (std:str:to_bytes ~ std:ser:json $[",
      "            :x => 10,",
      "            ${ y = 20 },",
      "        ]);",
      "",
      "!body = std:deser:json ~ std:str:from_utf8_lossy response.body;",
      "",
      "std:assert_eq body.url \"http://httpbin.org/post\";",
      "std:assert_str_eq body.json  $[ $[\"x\", 10], ${ y = 20 } ];",
      "std:assert_eq response.status 200;",
      "```",
      ""
    ]
  ],
  [
    "12.9.4 - std:http:request _http-client_ _method-string_ _url-string_ [_body-bytes_ [_headers-and-options-map_]]",
    [
      "",
      "This call is like `std:http:post` but makes HTTP requests with an almost",
      "arbitrary method with the optional given payload _body_. The rest of the",
      "options are the same as `std:http:get`.",
      "",
      "",
      "```wlambda",
      "!client = std:http:client:new[];",
      "!response =",
      "    std:http:request client :GET \"http://httpbin.org/get\";",
      "",
      "!body = std:deser:json ~ std:str:from_utf8_lossy response.body;",
      "std:assert_eq body.url \"http://httpbin.org/get\";",
      "```",
      "",
      "Or a POST request:",
      "",
      "```wlambda",
      "!client = std:http:client:new[];",
      "!response =",
      "    std:http:request client :POST \"http://httpbin.org/post\"",
      "        (std:str:to_bytes ~ std:ser:json $[",
      "            :x => 10,",
      "            ${ y = 20 },",
      "        ]);",
      "",
      "!body = std:deser:json ~ std:str:from_utf8_lossy response.body;",
      "",
      "std:assert_eq body.url \"http://httpbin.org/post\";",
      "std:assert_str_eq body.json  $[ $[\"x\", 10], ${ y = 20 } ];",
      "std:assert_eq response.status 200;",
      "```",
      ""
    ]
  ],
  [
    "12.10 - MQTT Messaging",
    [
      "",
      "WLambda offers an optional support for the MQTT protocol. You can setup a MQTT client",
      "as well as an embedded MQTT broker. The very simple integration offers you a very",
      "easy way to setup inter process communication between WLambda applications.",
      "",
      "Support for MQTT has to be explicitly compiled into WLambda by selecting the",
      "`mqtt` feature.",
      ""
    ]
  ],
  [
    "12.10.1 - std:mqtt:broker:new _config_",
    [
      "",
      "This function sets up an embedded MQTT broker. A handle is returned that you can use",
      "to publish messages using the locally connected client link.",
      "You can configure it's endpoints via the _config_.",
      "The _config_ offers following keys:",
      "",
      "```text",
      "${",
      "    id             = 0,                 # Broker ID",
      "    listen         = \"0.0.0.0:1883\",    # Broker server endpoint",
      "    console_listen = \"0.0.0.0:18088\",   # An extra HTTP console endpoint",
      "    link = ${                           # Configure the local link",
      "        client_id = \"some_id\",          # Link client ID, default is 'wl_local'",
      "        recv = <std:sync:mpsc channel>, # Channel to receive messages for the",
      "                                        # subscribed topics.",
      "        # Topics to subscribe to, if not given, '#' will be used:",
      "        topics = $[\"test/me\", \"another/topic\", ...]",
      "    },",
      "}",
      "```",
      "",
      "The default maximum MQTT payload the broker is setup to support is 10240 bytes",
      "(10 kb).",
      "",
      "Here is an example:",
      "",
      "```wlambda",
      "!broker = std:mqtt:broker:new ${",
      "    listen         = \"0.0.0.0:1883\",",
      "    console_listen = \"0.0.0.0:18080\",",
      "};",
      "",
      "# sleep a bit until the broker is initialized:",
      "std:thread:sleep :ms => 500;",
      "",
      "!chan = std:sync:mpsc:new[];",
      "!cl = std:mqtt:client:new chan \"test1\" \"localhost\" 1883;",
      "",
      "# let it connect:",
      "std:thread:sleep :ms => 200;",
      "",
      "!_ = cl.subscribe \"test/me\";",
      "!_ = cl.publish \"test/me\" $b\"test123\\xFF\";",
      "",
      "std:assert_str_eq chan.recv[] $p(:\"$WL/connected\", $n);",
      "std:assert_str_eq chan.recv[] $p(\"test/me\", $b\"test123\\xFF\");",
      "```",
      ""
    ]
  ],
  [
    "12.10.1.1 - broker.publish _topic-string_ _payload-bytes_",
    [
      "",
      "Publishes the _payload-bytes_ under the _topic-string_. Returns an error",
      "if something went wrong (client not connected, or some other error). It might",
      "block.",
      ""
    ]
  ],
  [
    "12.10.2 - std:mqtt:client:new _channel_ _client-id_ _broker-host_ _broker-port_",
    [
      "",
      "This sets up a MQTT client that connects to the given _broker-host_ and _broker-port_.",
      "It will connect and reconnect upon connection failure in the background automatically",
      "for you. So you don't have to manage the connection yourself.",
      "",
      "This function returns a client handle that is describe a little bit further below.",
      "",
      "The _client-id_ should be a unique ID to identify your MQTT client.",
      "",
      "The _channel_ must be a `std:sync:mpsc` channel that you can create using `std:sync:mpsc:new`.",
      "It's the source of incoming messages and connection control information.",
      "It will send you following possible message data:",
      "",
      "- `$p(:\"$WL/connected\", $n)`    - When the client connection was setup",
      "- `$p(:\"$WL/error\", \"some message here...\")` - When an error occurred in the connection handling.",
      "- `$p(topic, payload_bytes)` - An incoming MQTT message that belongs to the _topic_.",
      "",
      "Here is an example of a common client setup:",
      "",
      "```wlambda",
      "!broker = std:mqtt:broker:new ${",
      "    listen         = \"0.0.0.0:1883\",",
      "    console_listen = \"0.0.0.0:18080\",",
      "};",
      "",
      "# sleep a bit until the broker is initialized:",
      "std:thread:sleep :ms => 500;",
      "",
      "!chan = std:sync:mpsc:new[];",
      "!cl = std:mqtt:client:new chan \"test1\" \"localhost\" 1883;",
      "",
      "# let it connect:",
      "std:thread:sleep :ms => 200;",
      "",
      "!_ = cl.subscribe \"test/me\";",
      "!_ = cl.publish \"test/me\" $b\"test\";",
      "!_ = cl.publish \"test/me\" $b\"quit\";",
      "",
      "!got_some_stuff = $n;",
      "",
      "while $t {",
      "    !msg = chan.recv[];",
      "    match msg",
      "        $p(topic, $b\"quit\") => { break[]; }",
      "        $p(topic, data)     => { .got_some_stuff = std:copy $\\; }; # std:copy because $\\ is changing!",
      "};",
      "",
      "std:assert_eq got_some_stuff.topic \"test/me\";",
      "std:assert_eq got_some_stuff.data  $b\"test\";",
      "```",
      "",
      "The returned client handle understands the following methods:",
      ""
    ]
  ],
  [
    "12.10.2.1 - mqtt_client.publish _topic-string_ _payload-bytes_",
    [
      "",
      "Publishes the _payload-bytes_ under the _topic-string_. Returns an error",
      "if something went wrong (client not connected, or some other error). It might",
      "block.",
      ""
    ]
  ],
  [
    "12.10.2.2 - mqtt_client.subscribe _topic-string_",
    [
      "",
      "Subscribes to the _topic-string_. Returns an error if something went wrong.",
      "It might block.",
      ""
    ]
  ],
  [
    "13 - WLambda Lexical Syntax and Grammar",
    [
      "",
      "White space is everything that satisfies `std::char::is_whitespace`,",
      "so unicode white space is respected. Comments have the following syntax:",
      "",
      "```ebnf",
      "    comment = \"#\" ?anything except \"\\n\"? \"\\n\"",
      "```",
      "",
      "In the following grammar, white space and comments are omitted:",
      "",
      "```ebnf",
      "",
      "    ident_start   = ( ?alphabetic? | \"_\" | \"@\" | \"?\" )",
      "    ident_end     = { ?any character?",
      "                     - ( ?white space?",
      "                         | \".\" | \",\" | \";\"",
      "                         | \"{\" | \"}\" | \"[\" | \"]\" | \"(\" | \")\"",
      "                         | \"~\" | \"|\" | \"=\" ) }",
      "                  ;",
      "    qident        = ident_end",
      "                  (* a quoted identifier can not appear anywhere,",
      "                     it's usually delimited or follows something that",
      "                     makes sure we are now expecting an identifier *)",
      "                  | \"`\", { ?any character except '`'? }, \"`\" (* quoted identifier *)",
      "                  ;",
      "    ident         = ident_start, [ ident_end ]",
      "                  | \"`\", { ?any character except '`'? }, \"`\" (* quoted identifier *)",
      "                  ;",
      "    ref_specifier = \":\", qident",
      "                  ;",
      "",
      "    digit         = \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\"",
      "                  | \"6\" | \"7\" | \"8\" | \"9\"",
      "                  ;",
      "    integer       = digit, { digit }",
      "                  ;",
      "    radix         = integer",
      "                  ;",
      "    radix_digits  = (* digits in the radix specified",
      "                       earlier in the number.",
      "                       Default radix is of course 10. *)",
      "    number        = [ \"-\" | \"+\" ],",
      "                    [ ( radix, \"r\"",
      "                      | \"0\", \"x\"",
      "                      | \"0\", \"b\"",
      "                      | \"0\", \"o\"",
      "                      ) ],",
      "                    radix_digits,",
      "                    [ \".\", radix_digits ]",
      "                  ;",
      "    hexdigit      = ?hexdigit, upper or lower case?",
      "                  ;",
      "    ascii_c_name  = (* note: upper and lower case versions are possible *)",
      "                    \"NULL\" | \"SOH\" | \"STX\" | \"ETX\" | \"EOT\" | \"ENQ\" | \"ACK\"",
      "                  | \"BEL\" | \"BS\" | \"HT\" | \"LF\" | \"VT\" | \"FF\" | \"CR\" | \"SO\"",
      "                  | \"SI\" | \"DLE\" | \"DC1\" | \"DC2\" | \"DC3\" | \"DC4\" | \"NAK\"",
      "                  | \"SYN\" | \"ETB\" | \"CAN\" | \"EM\" | \"SUB\" | \"ESC\" | \"FS\"",
      "                  | \"GS\" | \"RS\" | \"US\" | \"DEL\" | \"SPACE\" | \"NBSP\"",
      "                  ;",
      "    string_escape = \"x\", hexdigit, hexdigit  (* byte/ascii escape *)",
      "                  | \"n\"                      (* newline *)",
      "                  | \"r\"                      (* carriage return *)",
      "                  | \"t\"                      (* horizontal tab *)",
      "                  | \"0\"                      (* nul byte/char *)",
      "                  | \"u\", hexdigit, { hexdigit }",
      "                                             (* unicode char, or in byte strings",
      "                                                their utf-8 encoded form *)",
      "                  | \"\\\"\"",
      "                  | \"\\'\"",
      "                  | \"\\\\\"",
      "                  | \"\\\\<\", ascii_c_name, \">\" (* the corresponding ascii value *)",
      "                  ;",
      "    string_lit    = string",
      "                  | character",
      "                  | \"$\", quote_string",
      "                  | \"$\", byte_string",
      "                  | \"$\", code_string",
      "                  ;",
      "    character     = \"'\", ( \"\\\\\", string_escape | ?any character? - \"\\\\\" and \"'\" ), \"'\"",
      "                  ;",
      "    string        = \"\\\"\", { \"\\\\\", string_escape | ?any character? - \"\\\\\" and \"\\\"\" },\"\\\"\"",
      "                  ;",
      "    byte_char     = \"b\", character",
      "                  ;",
      "    byte_string   = \"b\", string",
      "                  ;",
      "    quote_string  = \"q\", ?any character as quote?,",
      "                         { ?any character? },",
      "                         ?any character as quote?",
      "                  | \"Q\", ?any character as quote?,",
      "                         { ?any character? },",
      "                         ?any character as quote?",
      "                    (* but Q generates a byte string instead! *)",
      "    selector      = \"S\", ?any character as quote?,",
      "                         selector_rs_syntax,",
      "                         ?any character as quote?",
      "                    (* parses substring like 'q', but constructs a",
      "                       selector_rs_syntax matcher at compile time *)",
      "                  ;",
      "    pattern       = \"r\", [ \"g\" ], (* \"g\" for find all *)",
      "                         ?any character as quote?,",
      "                         selector_rs_pattern_syntax,",
      "                         ?any character as quote?",
      "                    (* parses substring like 'q', but constructs a",
      "                       pattern matcher at compile time *)",
      "                  ;",
      "    struct_match  = \"M\", expr   (* compiles expr as structure matcher function.",
      "                                   If called, it matches the first argument against",
      "                                   the literal structure and returns a map of",
      "                                   matched variables. If nothing matches $none",
      "                                   is returned. *)",
      "    formatter     = \"F\", string_lit (* compiles the string into a formatter, that",
      "                                       takes as many arguments as there are format",
      "                                       specifiers in the string. See also: String",
      "                                       formatting syntax in the next section. *)",
      "    list_expr     = \"*\", expr   (* splices the vector result of 'expr'",
      "                                   into the currently parsed list *)",
      "                  | expr",
      "                  ;",
      "    list          = \"[\", [ list_expr, { \",\", list_expr }, [ \",\" ] ],\"]\"",
      "                  ;",
      "    map_expr      = (ident | expr), \"=\", expr",
      "                  | \"*\", expr   (* splices the map result of 'expr'",
      "                                   into the currently parsed map *)",
      "                  ;",
      "    map           = \"{\", [ map_expr, { \",\", map_expr }, [ \",\" ] ], \"}\"",
      "                  ;",
      "    self          = \"s\" | \"self\"",
      "                  ;",
      "    true          = \"t\" | \"true\"",
      "                  ;",
      "    false         = \"f\" | \"false\"",
      "                  ;",
      "    none          = \"n\" | \"none\"",
      "                  ;",
      "    code_string   = (\"c\" | \"code\" ), block",
      "                  | (\"c\" | \"code\" ), expr",
      "                  ;",
      "    pair          = \"p\", \"(\", expr, \",\" expr, \")\"",
      "                  ;",
      "    err           = (\"e\" | \"error\"), expr",
      "                  ;",
      "    nvec          = (\"i\" | \"f\"), \"(\", expr, { \",\", expr }, \")\"",
      "                  ;",
      "    ref           = \"&&\", value",
      "                  ;",
      "    ref_hidden    = \"&\", value",
      "                  ;",
      "    ref_weak      = (\"w&\" | \"weak&\"), value",
      "                  ;",
      "    syntax        = \"%:\", {? any possible Syntax Type Identifier",
      "                             eg. \"Block\", \"Call\", ... ?}",
      "                    (* A syntax VVal, the possible identifiers are one of the",
      "                       possible result symbols of std:syn:type. This also",
      "                       saves the current parser position. *)",
      "                  ;",
      "    accumulator   = \"@\", (\"i\" | \"int\"",
      "                         |\"s\" | \"string\"",
      "                         |\"f\" | \"float\"",
      "                         |\"b\" | \"bytes\"",
      "                         |\"v\" | \"vec\"",
      "                         |\"m\" | \"map\" ), expr",
      "                    (* defines a new accumulator context *)",
      "                  | \"@@\" (* returns the current accumulator value *)",
      "                  | \"+\"  (* resolves to the current accumulator function *)",
      "                  ;",
      "    debug_print   = \"DEBUG\" (* evaluates to a debug print function that",
      "                               also prints source position and dynamic type.",
      "                               very useful for debugging. *)",
      "                  ;",
      "    import        = \"@import\", ident, [ ident ]",
      "                  ;",
      "    export        = \"@export\", ident, [ \"=\" ], expr",
      "                  ;",
      "    capture_ref   = \":\", var",
      "                  ;",
      "    deref         = \"*\", value",
      "                  ;",
      "    special_value = list",
      "                  | map",
      "                  | none",
      "                  | true",
      "                  | false",
      "                  | self",
      "                  | err",
      "                  | nvec",
      "                  | pair",
      "                  | ref",
      "                  | ref_hidden",
      "                  | ref_weak",
      "                  | deref",
      "                  | capture_ref",
      "                  | accumulator",
      "                  | selector",
      "                  | pattern",
      "                  | struct_match",
      "                  | debug_print",
      "                  | \"\\\"             (* The global variable with the name \"\\\" *)",
      "                  ;",
      "    arity_def     = \"|\", number, \"<\", number, \"|\" (* set min/max *)",
      "                  | \"|\", number, \"|\"              (* set min and max *)",
      "                  | \"|\", \"|\"                      (* no enforcement *)",
      "                  ;",
      "    function      = [ \"\\:\", ident ], \"{\", [ arity_def ], block, \"}\"",
      "                  | \"\\\", [ arity_def ], statement",
      "                  ;",
      "    var           = ident",
      "                  ;",
      "    symbol        = \":\", qident",
      "                  | \":\", \"\\\"\", (? any char, quoted \\\\ and \\\" ?), \"\\\"\"",
      "                  (*",
      "                     symbols are usually used to specify",
      "                     fields in literal map definitions",
      "                     and lots of other places as stringy sentinel values",
      "                  *)",
      "                  ;",
      "    value         = number",
      "                  | string_lit",
      "                  | \"$\", special_value",
      "                  | \"(\", expr, \")\"",
      "                  | function",
      "                  | symbol",
      "                  | var",
      "                  ;",
      "    op            = (* here all operators are listed line by line regarding",
      "                       their precedence, top to bottom *)",
      "                    \"&>\" | \"&@>\"      (* call rhs with lhs operator *)",
      "                  | \"<&\" | \"<@&\"      (* call lhs with rhs operator *)",
      "                  | \"^\"",
      "                  | \"*\" | \"/\" | \"%\"",
      "                  | \"-\" | \"+\"",
      "                  | \"<<\" | \">>\"       (* binary shift *)",
      "                  | \"<\" | \">\" | \"<=\" | \">=\"",
      "                  | \"==\" | \"!=\"",
      "                  | \"&\"               (* binary and *)",
      "                  | \"&^\"              (* binary xor *)",
      "                  | \"&|\"              (* binary or *)",
      "                  | \"&and\"            (* logical and, short circuit *)",
      "                  | \"&or\"             (* logical or, short circuit *)",
      "                  | \"=>\"              (* pair constructor *)",
      "                  | \"+>\"              (* take lhs, wrap it into list if not already",
      "                                         and append the right side.",
      "                                         if lhs is an iterator, append all elements. *)",
      "                  | \"<+\"              (* take rhs, wrap it into list if not already",
      "                                         and prepend the left side.",
      "                                         if rhs is an iterator, prepend all elements. *)",
      "                  ;",
      "    bin_op        = call_no_ops, { op, bin_op } (* precedence parsing is done",
      "                                                   in a Pratt parser style *)",
      "                  ;",
      "    arg_list      = \"[\", [ expr, { \",\", expr }, [ \",\" ] ], \"]\"",
      "                  | \"[[\", expr, \"]]\"  (* apply result vector of expr as argument list *)",
      "                  ;",
      "    field         = \".\", ( integer | ident | value ), [ field ]",
      "                  ;",
      "    field_access  = field, [ op ], \"=\", expr",
      "                  | field, arg_list",
      "                  | field",
      "                  (* please note, that a field access like:",
      "                     `obj.field` is equivalent to the call:",
      "                     `field[obj]`. That also means that",
      "                     `obj.field[...]` is transformed into",
      "                     `field[obj][...]`.",
      "                     The exception is \"=\" which assigns",
      "                     the field as specified.",
      "                     BUT: There is a special case, when you specify",
      "                          an identifier as field, it is quoted and",
      "                          interpreted as symbol. *)",
      "                  ;",
      "    call_no_ops   = value, { arg_list | field_access }",
      "                  ;",
      "    call          = value,",
      "                    { arg_list | field_access | bin_op | value },",
      "                    [ \"~\", expr ] (* this is a tail argument, if present the",
      "                                     expr is appended to the argument list *)",
      "                  ;",
      "    expr          = call, { \"|\", call }",
      "                  | call, { \"|>\", call }",
      "                  | call, { \"||\", call }",
      "                  ;",
      "    simple_assign = qident, [ op ], \"=\", expr",
      "                  ;",
      "    destr_assign  = \"(\", [ qident, { \",\", qident } ], \")\", \"=\" expr",
      "                  ;",
      "    definition    = [ ref_specifier ], ( simple_assign | destr_assign )",
      "                  ;",
      "    import        = \"!\", \"@import\", symbol, [ [ \"=\" ], symbol ]",
      "                  | \"!\", \"@wlambda\"",
      "                  ;",
      "    export        = \"!\", \"@export\", symbol, [ \"=\" ], expr",
      "                  ;",
      "    statement     = \"!\" definition",
      "                  | \".\" simple_assign",
      "                  | \".\" destr_assign",
      "                  | import",
      "                  | export",
      "                  | expr",
      "                  ;",
      "    block         = \"{\", { statement, \";\", {\";\"}}, [ statement, {\";\"} ], \"}\"",
      "                  | { statement, \";\", {\";\"} }, [ statement, {\";\"} ]",
      "                  ;",
      "    code          = block",
      "                  ;",
      "```",
      ""
    ]
  ],
  [
    "13.1 - Special Forms",
    [
      "",
      "There are certain calls that are handled by the compiler differently.",
      "",
      "- `if _condition_ _then-block-or-expr_ [_else-block-or-expr_]`",
      "- `while _condition_ _block-or-expr_`",
      "- `iter _var_ _value-expr_ _block-or-expr_`",
      "- `next _x_`",
      "- `break`",
      "- `match _value-expr_ $p(structure_pattern, branch_block) ... [ branch_block ]",
      "- `jump _idx-expr_ _block1_ ...`",
      ""
    ]
  ],
  [
    "13.2 - String Formatting Syntax",
    [
      "",
      "The `$F` special value takes a string and creates a formatting function.",
      "The syntax for formatting is very similar to Rust's string formatting:",
      "",
      "```ebnf",
      "    format_string = <text>, { maybe-format, <text> }",
      "                  ;",
      "    maybe-format  = '{', '{'",
      "                  | '}', '}'",
      "                  | <format>",
      "                  ;",
      "    format        = '{' [ argument ], [ ':' format_spec ] '}'",
      "                  ;",
      "    argument      = integer    (* index into argument vector *)",
      "                  | identifier (* requires a map as parameter *)",
      "                  ;",
      "",
      "    format_spec   = [[fill]align][sign]['#']['0'][width]['.' precision]['!' cast_type][type]",
      "                  ;",
      "    fill          = character",
      "                  ;",
      "    align         = '<' | '^' | '>'",
      "                  ;",
      "    sign          = '+' | '-'",
      "                  ;",
      "    width         = count",
      "                  ;",
      "    precision     = count | '*'",
      "                  ;",
      "    cast_type     = 'i'             (* interpret arg as integer *)",
      "                  | 'f'             (* interpret arg as float *)",
      "                  | 's'             (* (default) interpret arg as string *)",
      "                  ;",
      "    type          = 'x'             (* hex lower case *)",
      "                  | 'X'             (* hex upper case *)",
      "                  | 'b'             (* binary *)",
      "                  | 'o'             (* octal *)",
      "                  | 'j', character  (* a string join of a vector,",
      "                                       separated by 'character' *)",
      "                  | 'C', character  (* A CSV row, separated by 'character'.",
      "                                       This also supports proper",
      "                                       escaping using '\"' *)",
      "                  | 'J', ['p']      (* JSON, optional pretty printed *)",
      "                  | 'w', ['p']      (* print written WLambda representation,",
      "                                       optional pretty printed *)",
      "                  | ''",
      "                  ;",
      "    count         = parameter | integer",
      "                  ;",
      "    parameter     = argument, '$'",
      "                  ;",
      "```",
      ""
    ]
  ]
]