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
-
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
-
network graphs (e.g. State Machines)
-
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)
-
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
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)
-
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 (async)
-
History - remembered states
-
Actions - onEntry, onExit, transition
-
Guards - conditionally follow transitions (maybe don't go to the target state)
Statecharts: composite and parallel
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.
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 State Transitions, but...
The story of the addressId
Once there was an "add address" button
and button was coded to be active when addressId === null
so somebody 'a long time ago' made the button dynamic.
But then later in a different part of the code some one thought it was a good idea to set the addressId to null and they had no idea that the button changed behavior.
"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.
GSCC2019 State Machines for Programmer-less UIs
By Nate Morse
GSCC2019 State Machines for Programmer-less UIs
- 1,290