Reactive Framework Architectural Decisions
A set of architectural decisions affects how we make the reactive framework. These decisions also affect its capabilities.
Update Propagation
A key decision is how to deal with updating the program when values change.
Approach 1 · Re-execute the program
On every change, run the whole program again and reuse the parts that cannot have moved. One code path both builds the program and updates it. The state stays in step with the program's shape for free.
| Pros | Cons |
|---|---|
|
|
Approach 2 · A dependency graph chosen
Record every dependency as a graph: from each value to the calculations that read it, and from each calculation to the values it reads. A change walks only the dependents and recomputes them in order. The work matches what moved.
| Pros | Cons |
|---|---|
|
|
Approach 3 · Capture, then interpret
One initial pass builds a data structure describing the whole program, and execution then works over that structure. Description and running stay cleanly separate, and the captured program is portable and inspectable.
| Pros | Cons |
|---|---|
|
|
The decision
Reactive takes the second. It keeps a directed graph of every dependency in the program. When a value is set, it walks that graph and recomputes only the nodes downstream of the change, in order. Every input is settled before the node that reads it runs. The order comes for free. Nodes are grouped into scopes, and a node's inputs are built before it, so index order within a scope is dependency order. Scopes nest into a tree the walk descends. There is no separate sort and no heap. Each node recomputes once per change, always on final inputs.
A program also changes shape: a block appears, a list grows. For that, Reactive re-executes the section
that changed. An If whose condition turns true runs its block for the first time. An
Each runs its callback on each new element. This section-level re-execution sits alongside the
value-level recompute as a second, complementary kind of update.
| Change | What Reactive does |
|---|---|
| A value is set | Recompute its dependents in order, down the scope tree. |
| A section appears or disappears | Re-execute that section's builder, once, for the part that changed shape. |
Next Steps
We have the model: a dependency graph, recomputed in order down a tree of scopes, with section-level re-execution for shape changes. Next, Root starts to build it. Root is the container that holds the program as data. From there we add values, the dependency graph, then the rest.