Make illegal states unrepresentable
Planted 02024-07-24
Firstly, No silver bullet.
- State functions
- Type system
- Errors as values
- Parse, don’t validate
- Functional core, imperative shell
- Smart constructor
State functions
FSM: State and transition explosion
A finite-state machine (FSM) or finite-state automaton (FSA, plural: automata), finite automaton, or simply a state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some inputs; the change from one state to another is called a transition. An FSM is defined by a list of its states, its initial state, and the inputs that trigger each transition. Finite-state machines are of two types—deterministic finite-state machines and non-deterministic finite-state machines. For any non-deterministic finite-state machine, an equivalent deterministic one can be constructed.
The complexity of a traditional FSM tends to grow much faster than the complexity of the system it describes.
Hierarchically nested states
Statecharts, UML state diagrams, hierarchical state machines (HSMs)
Local vs global vs server
UI is a function of your remote state and your local state
References
- https://en.wikipedia.org/wiki/Finite-state_machine
- https://statecharts.dev/
- https://www.w3.org/TR/scxml/
- https://en.wikipedia.org/wiki/UML_state_machine
- https://en.wikipedia.org/wiki/State_pattern
- https://gameprogrammingpatterns.com/state.html
- https://geeklaunch.io/blog/make-invalid-states-unrepresentable/
- https://dev.to/davidkpiano/redux-is-half-of-a-pattern-1-2-1hd7
Type system
See Designing with types: Making illegal states unrepresentable
Discriminated unions
References
- https://basarat.gitbook.io/typescript/type-system/discriminated-unions
- https://v5.chriskrycho.com/journal/making-illegal-states-unrepresentable-in-ts/
- https://fsharpforfunandprofit.com/posts/designing-with-types-making-illegal-states-unrepresentable/
Errors as values
Return Error values from functions, do not throw/raise them.
This can be paired with discriminated unions.
https://jessewarden.com/2021/04/errors-as-values.html
Parse, don’t validate
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
Functional core, imperative shell
https://www.javiercasas.com/articles/functional-programming-patterns-functional-core-imperative-shell/
Smart constructor
Runtime checking.
https://wiki.haskell.org/index.php?title=Smart_constructors