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

Source Cells

Grammar

source_decl = "source" identifier cell_type_init [ cell_filter ] [ require_block ] ";".

A source declaration uses the same type and initializer rules as a cell, including evaluation without cell scope. It accepts an optional filter clause and require block. source, cell, and out share one namespace; declaring both source width and cell width is a “duplicate cell” error.

sheet resize {
    source width: i32 = 1920;
    source height: i32 = 1080;

    out area := width * height;
}

width and height supply inputs to the output that multiplies them.

Always a source, never derived

A source cell cannot be claimed as a method’s output, including in a conditional branch. Naming it on a binding’s left-hand side is an error. An out cell, by contrast, always has its own fixed writer.

A plain cell’s source/derived status is a per-round decision the solver makes from strength — the same cell might be a source in one round and derived in the next, depending on what’s been written recently. A source cell retains its last external write, or its initializer before any write. A filter may conform its effective value without changing that source value.

A source cell can be filtered too

A source cell can be read wherever a plain cell can and written directly by the host. A require block reports domain diagnostics:

sheet s {
    source width: i32 = 1920 require {
        @positive width > 0;
    };
}

A filter clause conforms its effective value during resolution, not during a write:

sheet s {
    source level: i32 = 50 filter 0..=100;
}