Learn · Hidden Machines · Part I
budding
Independent Lifecycles Need Independent State
State machines and product automata.
You will recover a finite-state transition from scattered callbacks, separate effects from the pure machine, and keep independent lifecycles independent by composing their states as a product.
A snapshot is not yet a story
The previous chapter gave a request four admissible alternatives. Now two callbacks race: received publishes data and cancel returns to idle. Is received legal after cancellation? The state type alone cannot answer.
Write a row for each pair of current state and event. A row either produces a next state and effect requests or rejects the event. That table is an automaton. Its carrier is the finite state set; its operation is transition.
The machine core should not fetch, render, or start timers. It returns effect descriptions. A handler interprets those descriptions at the edge. Tests can then replay start, cancel, received without a network or clock.
The laws are operational
For each event, transition is deterministic: the same state and event produce the same next state and requested effects. Every returned state belongs to the carrier—closure. Invalid events are represented deliberately rather than falling through a callback. Effects occur only when the handler interprets a returned request.
Characterization tests should first pin the observations of the tangled version: published view, requested effects, and their order. Only then can a reference transition table establish that the refactor preserves those observations.
Where the model stops
Do not build a workflow platform for a two-state toggle. A machine earns its name when transition legality matters. Product composition is also wrong when the coordinates are not independent—if opening the door mechanically stops a washer, that cross-invariant belongs in composition and may remove pairs from the reachable set.
Lessons
- Alternatives plus events form a state machine.
- A pure transition returns state and effect requests; a handler performs effects.
- Independent lifecycles compose as a product instead of a god enum.
- Reachability, not the Cartesian product alone, determines real system states.
Practice
- Reconstruct the transition rows for
idle --start--> loading --receive--> loadedand cancellation. - Decide whether “online/offline” and “authenticated/anonymous” are independent in a system where logout also closes the connection.
- Transfer the model to a washer's door and cycle states.
The machine is cleaner, but how will the next refactor prove it kept the right behavior?
References
- “David Harel, “Statecharts: A Visual Formalism for Complex Systems”.” — hierarchical and orthogonal state structure.
- “TypeScript Handbook, “Exhaustiveness checking”.” — making missing alternatives visible to the compiler.