C D E F scattered u per-node alloc/free u syscall overhead Arena alloc (fast) A B C D E F bump pointer contiguous u bump pointer u drop entire arena once No per-node free. Throw the whole arena away in one operation.
checks: String#length ✓ OK Frame 2 x = 42 ← reassign x .length x's type changes! type: Integer (box subscribed to type) Frame 3 // box re-runs x .length on Integer box checks: Integer#length ✗ NoMethodError No manual re-run. The box subscribes to the receiver — when type changes, it re-fires automatically.
reaction edge_b.add(T2) // trigger reaction edge_c.add(T3) // trigger reaction ⚠ inconsistent intermediate states With ChangeSet changes.queue(edge_a, T1) changes.queue(edge_b, T2) changes.queue(edge_c, T3) changes. apply() // all at once ✓ single consistent snapshot Boxes re-execute on the final state, not every intermediate.
{ line:12, col:30 } MethodCallBox carries location Diagnostic app.rb:12:30 // Output app.rb:12:30 error: undefined method `floor' for String puts User.new("Alice").greet.floor We never drop position info. Every node, every box, every diagnostic carries it.
Flow-sensitive type checking Abstract interpretation Graph-based type inference Annotations Required (.rbs) Required (inline sig) Not required Not required