Sign in

    dowdiness/incr/types does not have a README file

    BackdateEq

    pub(open) trait BackdateEq : HasChangedAt {
    fn backdate_equal(Self, Self) -> Bool = _
    }

    A backdate-aware equality check for memo outputs.

    The default implementation compares changed_at revisions: two values are considered "backdate equal" (i.e., the memo should not advance its changed_at) when both carry the same revision stamp. Override to provide custom logic.

    Supertrait

    Requires HasChangedAt — the type must expose a changed_at revision.

    HasChangedAt

    pub(open) trait HasChangedAt {
    fn changed_at(Self) -> Revision
    }

    A type that carries its own changed_at revision stamp.

    Implement this on value types that embed a Revision tracking when their content last changed. Used in combination with BackdateEq to enable O(1) backdate decisions based on revision comparison rather than O(N) structural equality.

    CycleError

    pub suberror CycleError {
    CycleDetected(CellId, Array[CellId], Array[String?])
    }

    Error type for cycle detection during memo computation.

    Returned by get_result() methods when a memo transitively depends on itself. Use cell(), path(), and format_path() to inspect or render the cycle. Labels are snapshotted at construction time so format_path is pure-value — rendering needs no runtime handle and reflects the cell labels at the moment the cycle was detected, even if those cells are later renamed or disposed.

    Example

    match memo.get_result() {
    Ok(value) => println("Got: " + value.to_string())
    Err(err) => {
    println("Cycle at cell " + err.cell().to_string())
    println(err.format_path())
    }
    }

    CycleError::cell

    fn CycleError::cell(self : CycleError) -> CellId

    CycleError::format_path

    fn CycleError::format_path(self : CycleError) -> String

    Formats the cycle path as a human-readable string, using captured labels when available and falling back to Cell[N] otherwise. Output longer than MAX_CYCLE_DISPLAY_STEPS entries is truncated with "→ ...".

    Example Output

    Cycle detected: self_ref → dep → self_ref

    CycleError::new

    fn CycleError::new(cell : CellId, path : Array[CellId], labels : Array[String?]) -> CycleError

    Construct a CycleError from its parts. Exposed so packages that detect cycles (and have access to a runtime for label lookup) can build the error without depending on variant-constructor visibility.

    Invariant: labels.length() == min(path.length(), MAX_CYCLE_DISPLAY_STEPS). The caller must uphold this — format_path assumes path[i] has a matching labels[i] for every i it renders.

    CycleError::path

    fn CycleError::path(self : CycleError) -> Array[CellId]

    Full dependency path leading to the cycle, untruncated. The path may include cells outside the cycle itself (e.g., entry points). Use the repeated cell to identify the cycle boundary.

    AccumulatorId

    pub(all) struct AccumulatorId {
    runtime_id : RuntimeId
    id : Int
    } derive(Eq,
    Debug
    )

    A unique identifier for an Accumulator in the runtime.

    Monotonically allocated by the runtime; never reused across dispose/new. Stale references to disposed accumulators resolve to "slot disposed" at verify time rather than aliasing to a recycled slot.

    Each AccumulatorId is scoped to its originating runtime via runtime_id.

    CellId

    pub(all) struct CellId {
    runtime_id : RuntimeId
    id : Int
    } derive(Eq,
    Debug
    )

    A unique identifier for a cell (signal or memo) in the runtime.

    Cell IDs are monotonically increasing integers allocated by the runtime. They serve as direct array indices for O(1) cell lookup.

    Each CellId is scoped to its originating runtime via runtime_id. This prevents cells from different runtimes being incorrectly queried against each other.
    impl Hash for CellId
    impl Show for CellId

    Durability

    pub(all) enum Durability {
    Low
    Medium
    High
    } derive(Compare, Eq,
    Debug
    )

    Classifies how often an input is expected to change.

    Durability enables a powerful optimization: when only low-durability inputs change, memos that depend solely on high-durability inputs skip verification entirely.

    Levels

    • Low: Frequently changing values (user input, source text)
    • Medium: Moderately stable values
    • High: Rarely changing values (configuration, schemas)

    Inherited Durability

    Memos inherit the minimum durability of their dependencies. A memo depending on both Low and High durability signals has Low durability.
    impl Show for Durability

    Durability::index

    fn Durability::index(self : Durability) -> Int

    Returns the numeric index of this durability level.

    Used internally for array-based durability tracking. Low has the smallest index (0), High has the largest (2). The invariant Durability::High.index() + 1 == DURABILITY_COUNT must hold — if a new variant is added, both this match and DURABILITY_COUNT must be updated together.

    Returns

    • Low → 0
    • Medium → 1
    • High → 2

    FunctionalRelationId

    pub(all) struct FunctionalRelationId[K, V] {
    id : CellId
    }

    GcRole

    pub(all) enum GcRole {
    Source
    Interior
    Root
    } derive(Eq,
    Debug
    )

    Categorizes a cell's role in garbage collection.

    • Source: Input cells (signals, relations) — no upstream deps, never collected
    • Interior: Derived cells (memos, reactives) — has deps, collectible when unobserved
    • Root: Terminal cells (effects) — keeps upstream alive, never collected
    impl Show for GcRole

    InternId

    pub(all) struct InternId {
    index : Int
    } derive(Compare, Eq,
    Debug
    )

    A stable integer key returned by InternTable::intern.

    Same value always maps to the same InternId within a table. IDs are monotonically increasing and can be used as array indices or MemoMap keys.
    impl Hash for InternId
    impl Show for InternId

    InternTable

    pub(all) struct InternTable[T] {
    to_id :
    HashMap
    [T, InternId]
    values : Array[T]
    }

    A grow-only interning table that assigns stable InternId keys to values.

    Interning guarantees that equal values always receive the same InternId, enabling cheap identity comparison (id1 == id2) instead of deep structural equality. Used by the bidirectional type-checker as MemoMap keys for cross-revision cache stability.

    InternTable::get

    fn[T] InternTable::get(self : InternTable[T], id : InternId) -> T

    Returns the value associated with id.

    Panics if id was not produced by this table.

    InternTable::intern

    fn[T : Hash + Eq] InternTable::intern(self : InternTable[T], value : T) -> InternId

    Returns the InternId for value, inserting it if not already present.

    InternTable::len

    fn[T] InternTable::len(self : InternTable[T]) -> Int

    Returns the number of unique values interned so far.

    InternTable::new

    fn[T : Hash + Eq] InternTable::new() -> InternTable[T]

    MemoId

    pub(all) struct MemoId[T] {
    id : CellId
    }

    ReactiveId

    pub(all) struct ReactiveId[T] {
    id : CellId
    }

    ReadError

    pub enum ReadError {
    Cycle(CycleError)
    Disposed(CellId)
    }

    Error type for the public read channel.

    A read asks for a stored graph snapshot, so the only failures it can report are mechanism failures — intrinsic to the read itself and unrecoverable by any domain reader:

    • Cycle — the cell transitively depends on itself.
    • Disposed — the cell being read has been disposed.

    Domain fallibility (a parse error, a validation failure) is not a read error: it belongs in the value as Result[V, E] (see Derived::fallible), where it is cached, change-detected, and replayed like any other value. A retained compute raise Failure is a defect, not a domain error, and still aborts.

    Cross-runtime misuse and strict-context misuse are programmer defects and abort rather than surfacing here.

    See docs/design/specs/2026-05-28-honest-read-error-ownership.md.
    impl Show for ReadError

    ReadError::cell

    fn ReadError::cell(self : ReadError) -> CellId

    Returns the cell this read error concerns: the cell at which the cycle was detected, or the disposed cell that was read.

    ReadError::cycle

    fn ReadError::cycle(e : CycleError) -> ReadError

    Constructs a cycle read error. Exposed so the cells package (which detects cycles) can build a ReadError without depending on variant-constructor visibility — mirrors CycleError::new.

    ReadError::disposed

    fn ReadError::disposed(id : CellId) -> ReadError

    Constructs a disposed-cell read error.

    ReadError::format_path

    fn ReadError::format_path(self : ReadError) -> String

    Renders this read error as a human-readable string. For a cycle, delegates to CycleError::format_path; for a disposed read, names the cell.

    ReadError::is_cycle

    fn ReadError::is_cycle(self : ReadError) -> Bool

    Returns true if this is a cycle error.

    ReadError::is_disposed

    fn ReadError::is_disposed(self : ReadError) -> Bool

    Returns true if this is a disposed-cell error.

    ReadError::path

    fn ReadError::path(self : ReadError) -> Array[CellId]

    Returns the cell path this read error concerns: the full dependency path leading to the cycle, or the single disposed cell that was read.

    RelationId

    pub(all) struct RelationId[T] {
    id : CellId
    }

    Revision

    pub(all) struct Revision {
    value : Int
    } derive(Compare, Default, Eq,
    Debug
    )

    A monotonically increasing revision counter representing the system's logical clock.

    Revisions are bumped each time an input signal changes. Every cell tracks two revision timestamps:

    • changed_at: When this cell's value last actually changed
    • verified_at: When this cell was last confirmed up-to-date

    A cell is stale when verified_at < current_revision. A cell has changed (relative to an observer) when changed_at > observer.verified_at.

    Revision::initial

    fn Revision::initial() -> Revision

    Returns the initial revision (revision 0).

    All cells start with changed_at and verified_at set to this value.

    Returns

    The initial revision

    Revision::next

    fn Revision::next(self : Revision) -> Revision

    Returns the next revision in sequence.

    Returns

    A new revision with value incremented by 1

    RuleId

    pub(all) struct RuleId {
    id : CellId
    }

    RuntimeId

    pub(all) struct RuntimeId {
    id : Int
    } derive(Eq, Hash,
    Debug
    )
    fn RuntimeId::RuntimeId(id : Int) -> RuntimeId

    A unique identifier for a Runtime.

    Runtime ids are monotonically allocated when a Runtime is created and scope every CellId / AccumulatorId to its originating runtime.

    A RuntimeId is an introspection / debug identity: compare it for equality ("are these two runtimes the same?"), use it as a map key, or display it. It is not a stable application key across program runs, and carries no ordering or arithmetic meaning — that is why it is a nominal wrapper rather than a bare Int.
    impl Show for RuntimeId

    SignalId

    pub(all) struct SignalId[T] {
    id : CellId
    }

    DURABILITY_COUNT

    let DURABILITY_COUNT : Int

    The number of durability levels (3: Low, Medium, High).

    Must equal Durability::High.index() + 1. Adding a new Durability variant requires updating both Durability::index() and this constant; failing to do so will silently under-size the durability_last_changed array in Runtime, causing incorrect fast-path revision checks.

    MAX_CYCLE_DISPLAY_STEPS

    let MAX_CYCLE_DISPLAY_STEPS : Int

    Maximum number of path entries rendered by CycleError::format_path, and the number of labels snapshotted at error-construction time.

    Cycles longer than this are truncated in the formatted output with "→ ...", but CycleError::path() still returns the full untruncated sequence.