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

Outputs and Requirements

Grammar

out_decl    = "out" identifier [ ":" type_expr ] ":=" expression
               [ cell_filter ] [ "require" "{" { requirement } "}" ] ";".
requirement = [ "@" identifier ] expression ";".

An out declares a cell computed by one expression, with deduced dependencies. The optional : type_expr annotation must match the expression’s type; without it, Adam infers the type. An output may also carry a filter clause.

sheet area_demo {
    source width = 10 filter 0..=100;
    source height = 20 filter 0..=100;

    out area := width * height;
}

An output cell can be read anywhere, written nowhere

An output shares the cell namespace and must have a unique name. Later declarations may read it as a relationship input, conditional subject, filter argument, or another output’s input. Only its own expression may write it: host writes, relationship bindings, and additional out declarations cannot. The expression is purely functional; resolution may reuse its result:

sheet s {
    source width: i32 = 10;
    out area := width * 2;
    out doubled_area := area * 2;
}

Requirements: diagnostics, not gates

A require { ... } block attaches zero or more boolean checks to a cell, source, or out declaration, after any filter. Each requirement deduces its dependencies separately from the initializer. It may read the cell it checks and any other declared cells:

sheet area_demo {
    source width: i32 = 10;
    source height: i32 = 20;

    out area: i32 := width * height require {
        @not_too_big area <= 300;
    };
}

Requirements are purely functional predicates of their input values and immutable constants, with no externally observable side effects or mutable external dependencies. Equal inputs produce equivalent results or errors. There is no guarantee that a requirement executes, or when or how often it executes; current diagnostics may use a previously computed result.

A failed requirement does not stop resolution or prevent a cell’s value from being computed and read. Hosts can query failures through the embedding API. The optional @name identifies a requirement for reporting; it is not a cell reference.

Multiple requirements

A declaration can list any number of requirements, which hosts can query individually:

sheet bounds_demo {
    source x: i32 = 50;

    out clamped: i32 := x require {
        @not_negative clamped >= 0;
        @not_too_big clamped <= 100;
    };
}