State Machines for a Programmer-less UI
A data-structure that can define user interfaces in a declarative, visual format.
Exploring "what are" and "why use" State Machines using XState with React.
with Nate Morse
Bret Victor
The Future of programming 2013
David Harel
Statecharts: A Visual Formalism for Complex Systems 1987
David Khourshid
XState 2015
From State Machines to Statecharts
Leonhard Euler
Graphs as a thing 1736
conventions and standard coding practices
the Road less Traveled
Confirmation Bias
now arriving at Statecharts
-
That ain't coding.
-
Dare to declare!
-
XState - demo time...
-
Is programming even in your future?
That ain't coding.
You are now entering a "no coding zone!"
Let's acclimatize by looking at a few data-structures:
-
stacks
-
trees
-
network graphs (e.g. State Machines)
-
multi-layer neural networks
-
stacks
(formalism #1)- so simple that we don't really need the data-structure formalism -- we could just use an array in a disciplined way.
- But its better to abstract away the implementation so that later that can be changed (array <--> linked list)
- A formalism is there to protect us from ourselves, in a weaker moment. (e.g. we really should not cheat)
-
trees (formalism #2)
- Trees are more more powerful than stacks
- Even a better argument for using a formal interface (refrain from accessing the underlying data directly -- cheating).
-
network graphs and State Machines (formalism #3)
- A network graph is made of nodes and edges (circles and arrows)
- A State Machine calls these "states" and "transitions" (nodes and edges)
- There is always a current state (defaults to an initial state)
- What it does: On an input signal a matching transition will be followed to a new (current) state
-
multi-layer neural networks (formalism #4)
very little coding happens here.
Finite State Machines to Statecharts
Which are more or less powerful
-
Expressions
-
State Machines
-
Statecharts
-
Turing Machines
more expressive
easy to reason about
can prove correct
What you get out of the box with an FSM
States (stopping points)
Transitions (paths from one state to another)
Start State (always in some state)
Final or Accepting States (optional)
Introspection (graph traversal algorithms)
Finite State Machines
Finite State Machines
PR process fsm graph
Statecharts
What you get out of the box with XState
-
Composite - nested states (Hierarchy)
-
Orthogonal - parallel states
-
History - remembered states
-
Actions - onEntry, onExit, transition
-
Guards - conditional transitions
Statecharts
Composite states
(Hierarchy)
State Machine
State Machine
Statechart
Statechart
Parallel states
(Orthogonality)
Statecharts
1970's Citizen watch
State Machines to Statecharts
usefulness -->
number of states -->
https://www.desmos.com/calculator/fywfdcsqxr
FSM
State Machines to Statecharts
usefulness -->
number of states -->
https://www.desmos.com/calculator/fywfdcsqxr
composite states
FSM
State Machines to Statecharts
usefulness -->
number of states -->
https://www.desmos.com/calculator/fywfdcsqxr
FSM
parallel states
history states
composite states
guards
State Machines to Statecharts
usefulness -->
number of states -->
https://www.desmos.com/calculator/fywfdcsqxr
FSM
parallel states
history states
composite states
guards
Procedural
If you list out the steps needed, the CPU will proceed to do that. You must make sure that all resources are in place before any step is executed.
Declarative
If you describe what your app will do (in a diagram perhaps) how it will interact with the world, Then you have codified the requirements.
Let a State Machine orchestrate the steps needed to get to the goal.
Tell your computer what needs to be done, not how to go about doing it.
What connects your code to the specifications?
Answer: hard work
but if we Dare to Declare
we get a unified representation of what our app should and will do
Diagrams
JSON data
{
initial: 'idle',
states: {
idle: { on: {SUBMIT: 'loading' } },
loading: { on: {PF: 'error' ,
PR: 'success' } },
success: { },
error: { on: { SUBMIT: 'loading' } }
}
}
What about Redux
and other state management libs?
Redux gives us a clean way to separate state from our UI and that helps manage changing state, but what state changes to is 'coded' in a (perhaps too powerful) function.
"Reducer" functions are simply, State Transitions!
-
reducers are the Redux's way of changing state, to understand it, takes a developer to decipher what a reducer will do.
-
State transitions are more accessible to UX, Design Devs, QA ... For all to see, form any state, what the next state will be
"Any sufficiently complicated model class contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a state machine."
-- colleague of R. Braithwaite
"Any sufficiently complicated model class contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a state machine."
state management library
-- colleague of R. Braithwaite
XState & React
Let's see how these concepts fit into the reality of building a UI
Our Example: "Amendments"
Just complex enough to explore in half an hour.
An Application for Lawmakers.
Enable Legislators to make changes to laws.
Amendments (demo)
Demo Time... XState
$ npx create-react-app some-xstate-app
$ cd some-xstate-app
$ npm install xstate --save
... create a state machine ...
. . . Make some UI components . . .
$ npm start
... watch your state machine run ...
OR git clone https://github.com/nmorse/amendments.git
Is programming even in your future?
If our programming practices do not change, we could easily replicate past mistakes, while the complexity and volume of code that will soon need to be written will overwhelm us.
Does your code represent the specifications?
- Our code is an approximation of the specifications. Only by meticulously maintaining the docs and code to match (as much as possible)
+ Statecharts declaratively are the specifications.
Some Pros
-
specifications are shared in a common language (a visual representation)
-
predictable state mutations (transitions are traceable)
-
easy to reason about because it is less expressive
-
you can't cheat
and Cons
- diagrams are not guaranteed to communicate well
- a different approach is not always better
- something more to learn
- less expressive
- you can't cheat
Finite State Machines & Statecharts
Where to go from here?
Further topics:
- testing (model based testing)
- extended crafting of Statecharts (learning how the build them to make complex applications that are not complex to maintain)
Thank you for exploring Statecharts with me.
State Machines for Programmer-less UIs
By Nate Morse
State Machines for Programmer-less UIs
- 1,915