Two derived values read one state source and a third reads both — what is a glitch, and how is it prevented?
answer
- the diamond shape
- mixed-generation inputs
- a value no state justifies
- settle in dependency order
- mark dirty, pull on read
basics
~20 sA glitch is an evaluation with one input refreshed and the other stale, producing a value no state justifies. Runtimes prevent it by settling dependents in dependency order: ordered propagation, marking dirty and refreshing on read, or batching a turn.
solid answer
~50 sThe shape is a diamond: one source, two derivations over it, and a consumer reading both. A glitch is an evaluation of that consumer with mixed-generation inputs — one refreshed, one stale — so it computes a value matching neither the old state nor the new. It matters because an intermediate that escapes into a side effect or onto the screen cannot be taken back, and it reproduces badly. Runtimes avoid it by never evaluating a dependent before its own inputs are current: propagating in dependency order, or marking dependents dirty on write and refreshing ancestors depth-first when a reader pulls, or batching a turn's writes and settling once. What is left to you is keeping the chain inside the graph the runtime observes — and collapsing two derivations into one removes the diamond entirely.
go deeper
Know the vocabulary: derived values can read other derived values, forming a chain, and the runtime is responsible for updating them in a sensible order.
Describe the diamond and the symptom: a consumer evaluated with one input refreshed and one stale produces a value that matched no state at all.
Show how you would find such a bug and which fix you would reach for, including collapsing the diamond into one derivation when no reader needs the intermediates.
Reason about what the guarantee does not cover. Anything outside the observed graph — a parked intermediate, two values kept in step by hand — is a correctness risk the team owns.
Derived values chain. One derivation reads state; another derivation reads the first; a third reads both. Draw the dependencies and you get a **diamond**: a single source at the top, two paths down, and a consumer at the bottom that reads both paths. The diamond is where a specific class of bug lives. ## What a glitch is A **glitch** is an evaluation of a dependent value with a **half-updated set of inputs** — one input already reflecting the new state, another still holding the old. The result is a value that corresponds to no state the application was ever in. Consider a source `n`, a derivation `double = n * 2`, a derivation `plusOne = n + 1`, and a consumer that reads `double - plusOne`. With `n = 4` the consumer sees `8 - 5 = 3`. Set `n` to `5`: if the consumer runs after `double` updates but before `plusOne` does, it computes `10 - 5 = 5` — a number that is wrong for both the old and the new `n`. Then it runs again and settles on `10 - 6 = 4`. Two things make this worse than a wasted evaluation: - If the consumer has a side effect — a request, a log line, a write to somewhere outside the framework — the intermediate value **escapes** and cannot be taken back. - If the consumer is displayed, a reader can see the impossible value for one frame, and bug reports of that kind are almost impossible to reproduce by hand. ## How runtimes avoid it A runtime that simply notified each dependent the moment its own input changed would glitch routinely. Real designs use one or more of: 1. **Ordering.** Compute dependents in dependency order, so nothing runs until everything it reads has been brought up to date. This requires the runtime to know the graph, which is exactly what a tracked or declared dependency set gives it. 2. **Mark dirty, then pull.** A write does not recompute anything; it marks dependents stale. A read walks up, refreshes stale ancestors first, then computes. Because the walk is depth-first from the reader, a consumer is never evaluated before its own inputs are current. 3. **Batching into one pass.** Writes within a turn are collected and the graph is settled once afterwards, so intermediate combinations are never published to consumers. 4. **A version or epoch counter.** Each value carries the revision of the state it was computed from; a consumer that sees mismatched revisions refreshes instead of combining them. Frameworks differ, and the contrast is worth carrying: a runtime that re-runs the whole component function recomputes every derivation inside it from one snapshot of state, so a diamond entirely inside that function cannot glitch, while a fine-grained runtime that propagates value by value must order or batch its propagation to get the same guarantee, and a compile-time runtime emits the ordering as generated code. The guarantee has the same name in each; the mechanism that provides it does not. ## What remains yours to get right The framework's guarantee covers the graph it can see, which leaves real work on your side: - **Keep the chain inside the graph.** A step that stashes an intermediate result somewhere the runtime does not observe, and reads it back later, is outside the ordering and can be combined with a fresh sibling. - **Derive, do not mirror.** Two derivations kept in step by hand, each updating the other's source, has no order for the runtime to respect. - **Watch side effects on combined values.** Work triggered by a combination of two derived inputs is the place where an intermediate value does damage; a glitch-free runtime is what keeps it from firing on an impossible pair, so do not defeat that by reading the inputs through a path the runtime cannot see. - **Prefer one derivation over two.** If a consumer only ever needs `double - plusOne`, expressing that as a single derivation from `n` removes the diamond instead of relying on the runtime to settle it. ## How to talk about it Name the shape, name the symptom, name the fix. The shape is a diamond: two derivations over one source, combined by a third. The symptom is an evaluation with mixed-generation inputs producing a value no state justifies. The fix is that dependents are settled in dependency order — by ordered propagation, by marking dirty and pulling on read, or by batching a turn into one settle pass — and the reason it matters is that an escaped intermediate becomes a request, a log line or a visible flash. Add that a runtime cannot order what it cannot observe, and you have said the part senior interviewers are listening for.
- Why is a glitch worse than a merely wasted extra evaluation?A wasted evaluation costs time and is then discarded. A glitch produces a value that never corresponded to any application state, and if the consumer has a side effect — a request, a log line, a write outside the framework — that impossible value escapes and cannot be recalled. On screen it can appear for a frame, which makes the bug report nearly impossible to reproduce by hand.
- How can you defeat a runtime's glitch-free guarantee from your own code?By taking a step out of the graph the runtime can see. Stashing an intermediate result somewhere unobserved and reading it back later removes that edge from the ordering, so the value can be combined with a freshly refreshed sibling. Two derivations kept in step by hand, each writing the other's source, have no order for the runtime to respect either.
- When would you collapse a chain of derivations into one instead of relying on the runtime?When no reader needs the intermediates. If the only consumer wants the combination, expressing it as a single derivation from the source removes the diamond, one cache instead of three, and one thing to reason about. Keep the intermediates when several consumers genuinely read them, or when one of them is the expensive step you want cached separately.
It is a currency conversion where the rate updates before the amount does: for one instant the screen shows a total that was never true for either the old amount or the new one.
saying these in an interview costs you the question
- Thinks a glitch is just a wasted recomputation with no visible effect
- Believes any push-based propagation is automatically glitch-free
- Cannot name the diamond shape where the problem arises
- Assumes batching alone orders dependents correctly in every case
- Expects the runtime to order a step it never observed