Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Declarations

A file is a sequence of declarations. The order does not decide visibility: names in one section see each other, and a call may precede the declaration it names.

pub may precede a declaration that sits in a section. Without pub, the declaration is visible to that section and the sections nested inside it.

func

func name(param: Type, …) -> Result / {Effects} { body }
func name<+T, …>(param: Type) -> Result { body }
func name(consumer: Type) <- Input / {Effects} { body }

The value parameters are one group. -> returns a value. <- produces a consumer of Input; each parameter on a <- function is a consumer, and the positive type written on it is what that consumer accepts. A bare arrow has an empty effect row.

A type parameter carries a sign: + positive, - negative, * either. An unsigned parameter is a row, used as ..E. Bounds are written on the parameter, <+T: Eq + Display>.

fn

fn is an expression, listed here because it is the unnamed form of func.

fn(param: Type, …) -> Result { body }
fn { body }

A nullary lambda's name denotes the function. Calling it is f() or <(,) | f.

proc

proc name(value: Type, …) | (exit: Consumer, …) / {Effects} { body }

The body is a command. Every terminating path cuts to one of the exits. The exit row is a bundle: positional, invariant in width and order. main is a proc at the root with no value parameters and one exit, the status.

data and enum

data Name<+T> { field: Type, … }
enum Name<+T> { Variant, Variant(Type, …), … }

A data value carries every field. An enum value carries exactly one variant. A variant with no payload is a value of the enum. A variant with a payload is a constructor, and several payload types are one tuple. Type parameters on data, enum, menu, and form take signs and do not take trait bounds.

menu Name<+T, E> / {..E} {
    item: Type,
    item(param: Type, …): Type,
}

form Name / {Effects} { field: Type, … }

A menu answers one item the consumer demands. A field with parameters is the function of those parameters, and the answer type is that function's result. A form wants every field at once. Both are built with mu. The effect row on the declaration is performed when the value is demanded.

spec and impl

spec Name<+U>: Parent + Parent {
    type Item;
    func method(self: Self, …) -> Result / {Effects};
    func method(self: Self) -> Result { body }
}

impl<+T: Bound> Name<Arg> for Type {
    type Item = Concrete;
    func method(self: Type, …) -> Result { body }
}

Self is the implementing type. A method body in the spec is a default, copied into an impl that omits it. See Traits.

hook, hand, and hn

hook Name<+T, E> {
    func operation(arg: Type, …) -> Result;
}

hand name / {Residual} {
    operation(arg): resume => body,
    _ => forward,
}

A hook declares an effect. A hand declares a handler and is not a value; each do expr name inlines it. hn is an expression that builds a handler value. See Effects and handlers.

def

def NAME: Type = expression;

def binds a constant. The name sits on neither side of the value and continuation mirror, which is why the keyword is def.

sect and cite

sect name { declarations }
sect name;
cite path::name;
cite path::*;
cite Enum::{Variant, Variant};

See Sections and files.