Glossary
All the documentation's terminology in one place, in plain words. Terms are grouped by theme; pages link to them by anchor.
The model of time
State
A value across time. At any moment you can ask a State "what are you right now?" — and there is always an answer: sample() responds whether or not anybody is listening. The text of an input, the current user, the mouse position: they exist at every moment, even when nobody is looking. Formally, a function from time to value (Time → A). Called Behavior in the FRP literature; previously named Wire in Continuum. A source state (state(init)) is written with .set(value) and .update((state) => next) — the updater folds over the value staged by the current moment, so several updates in one batch compose. More: States.
Behavior
Deprecated alias for State — the FRP-literature name for a value across time (Elliott & Hudak, 1997; the Sodium book). The alias still works today and will be removed in 1.0.
Stream
A stream of happenings. Unlike a State, you cannot ask an event "what are you now" — between firings it simply isn't. A click, a keypress, a server response: not values that exist, but things that happen. More: Streams.
Occurrence
One firing of an event. A pair of "moment + value": the third click, one specific server response. When we say "a Stream is discrete occurrences", we mean: an event is a set of individual firings, not a continuous quantity.
Discrete
Made of separate points rather than continuous. Discrete time is a sequence of individual moments (a tick, a click, a response) with nothing in between. The opposite is continuous time, as in physics. Continuum is discrete FRP: change happens in transaction-moments.
Moment / transaction
One atomic "tick" of logical time. Everything that follows from one event — all derived values — recomputes inside a single moment, as one whole: from outside you can never see "half" an update. "Logical" time because moments are counted by order, not milliseconds — only before/after/simultaneous matters. More: Transactions and time.
Simultaneity
Two occurrences in one moment. In callback world, "simultaneous" events actually run in some arbitrary order. In Continuum simultaneity is real: two events in one moment see the same world, and merging them (merge) forces you to say what to do with the pair.
Coalescing
Folding simultaneous occurrences into one. When two events happen in the same moment but one must come out, the coalescing function ((a, b) => … in Stream.merge) combines them. Without it you'd have to pick "who was first" — which is a race. A state's updates works the same way: however much happens inside a moment, it delivers exactly one coalesced occurrence for it.
Glitch
Observable half-updated state. The classic reactive-systems bug: sum = a + b where a has updated but b hasn't yet, and for an instant sum shows nonsense. In Continuum glitches are impossible by construction — a moment is atomic. The "diamond" example: Transactions and time.
Diamond
The dependency shape where glitches show up. One value feeds two branches which reconverge in a shared descendant: count → doubled, count → squared, doubled + squared → sum. Naive reactivity recomputes sum twice (the second time as a correction); a transaction does it once, correctly.
The hold delay
The rule: a State updates at the moment's boundary. Within the moment an occurrence arrives, hold/accum still show the old value. Sounds odd, but this is exactly what makes "the current value" well-defined when you look at it from the event that is changing it: the past is stable, the present is still forming. More: Transactions and time.
Fold
Accumulating an event's history into one value.clicks.accum(0, (_e, n) => n + 1) — "start at 0 and add 1 per click": a counter is a fold of clicks. The same move as Array.reduce, but over time instead of over an array.
push / pull
Two ways of delivering values. Streams push: something happened — it propagates through the graph. States pull: the value is computed when asked. Continuum is a hybrid: changes propagate by pushing, sample() reads by pulling.
Formulas vs state
Values are formulas; state and effects belong to a scope. A pure derived value (map, combine) is a recipe: it computes on demand, sleeps while nobody listens, and sample() still always answers. Anything that remembers or does — hold, accum, state, perform, .on — needs an owner: inside a component the scope is automatic; at module level you spell the lifetime out with root().
The network
Network / dependency graph
Everything you built out of States and Streams. map, combine, merge, at connect quantities into a directed graph: nodes are values and events, edges are "computed from". A component builds its piece of the graph once; updates flow through it afterwards.
Rank
A node's depth in the graph. The internal mechanism of glitch-freedom: nodes recompute in rank order (sources first, then deriveds, then deriveds of deriveds), so a node never fires before its inputs. You never touch ranks — they are just there.
at
An event photographs a value. draft.at(clicks, (text, click) => …) — "at the moment of the click, take the field's text"; draft.at(clicks) takes it as-is. The FRP replacement for the habit of "I'll read the variable inside the handler", but with exact semantics: at sees the value before the current moment (see the hold delay). The FRP literature calls this snapshot.
sample
Read a State's current value directly. s.sample() always answers — it is for code outside the network: initialization, tests, integrating foreign code. Inside the network prefer at — its simultaneity is defined.
Hatch
An explicit door between the pure network and the outside world. In: stream() / state() (inject a value). Out: listen (run a side effect), perform (do IO and return the result as an event). The word emphasizes that the network's boundaries are visible in the code, not smeared everywhere.
Result
An error as data. { ok: true, value } | { ok: false, error } — the outcome of IO where failure is an ordinary value branch, not a thrown exception. You can filter errors, accumulate them, render them — like any data.
Rendering
Fine-grained rendering
Exactly what depends on a value updates. Not "re-render the component and diff", but "this text node is bound to this State — patch it". This is why components run once and there is no virtual DOM.
Binding
A live link State → a piece of DOM. {count} in JSX doesn't mean "insert the current value"; it means "this text node now shows count, forever". Same for attributes: class={cls}.
Re-render
A foreign concept (React) we define ourselves against. Re-running a component function to compute a new tree. Continuum has none: a component runs once, updates travel through bindings.
Dynamic region
A stretch of DOM rebuilt from a value. The dyn primitive (and its sugar — Show, Dynamic): a subtree lives between comment markers; when the driving value changes, the old subtree is disposed and a new one is built. Values change bindings; structure changes through regions. More: Conditional rendering.
Keyed reconciliation / LIS
Matching list rows by key and reordering minimally. <Each> keeps one live subtree per key; on reorder it computes the longest increasing subsequence (LIS) and moves only what actually moved. More: List rendering.
last-request-wins
The response-race rule: the latest request wins. If the user asked for page 2 and then page 3, a late response for "2" is ignored. resource solves this internally by numbering requests.
Chunk / code splitting
Cutting the bundle into pieces loaded on demand. A literal import("./Page") in the code signals the bundler to emit a separate file (chunk), downloaded on first visit. Here — via the router's lazy.
Lifecycle
Ownership tree
Whoever builds it cleans it up. Everything a component creates (subscriptions, timers, nested regions) registers with its "owner"; disposing a subtree releases resources in a cascade — children first, then the parent. More: Ownership and lifecycle.
Scope
One node of the ownership tree — the owner of state and effects. Every component, dynamic region and <Each> row creates its own scope: it has its own onCleanup/onMount, the state (state, hold, accum) and processes (.on, perform) created inside register with it, and it dies as a whole. Pure formulas need no scope — they are just recipes.
root()
An explicit lifetime for module-level state. Inside a component, state gets its scope automatically. At module level there is no component to own it, so you say who does: const store = root(() => …) creates a top-level scope that owns everything built inside. Creating hold/accum/perform with no scope at all is a teaching error, not a silent leak.
Error boundary
A safety net for a piece of the page. If building or rebuilding a subtree throws, the nearest <Catch> above it disposes the broken subtree (with all its subscriptions) and shows a fallback instead of killing the whole app. More: Conditional rendering.
Cascading cleanup
Disposing a subtree frees everything inside automatically. A page goes away — its subscriptions unsubscribe, its timers stop, its portaled modals vanish. No "on unmount, remember to…" — the ownership tree remembers for you.
Context
Values available to descendants without prop drilling. provide puts a value into the current owner, use looks it up through ancestors. More: Context.
The wider world
Classic (discrete) FRP
The branch of FRP Continuum belongs to. Time is a sequence of transactions; combinators have exact semantics (Sodium, the Blackheath & Jones book). Contrasted both with Elliott's continuous FRP (time as in physics) and with the "reactivity" of signals/Rx. See History and context.
Denotational semantics
Defining constructs by mathematical meaning, not by implementation. "merge is the union of occurrence sets with coalescing of simultaneous ones" — an equation you can prove properties from (glitch-freedom, for one), not a description of a loop in code.
Signals
The neighboring reactivity tradition (Solid, Vue, Angular, TC39). Dependencies are tracked automatically when a value is read; the graph is implicit. Convenient to write; harder to reason about. The comparison lives in History and context.
The synchronous hypothesis
The 1980s synchronous-languages idea: a reaction is conceptually instantaneous. While the system reacts to an event, new events "wait outside" — which makes each reaction atomic. Continuum's transactions are a direct inheritance of this idea.