[Image: REUTERS/Mario Anzuoni]
State Machine - just the juxtaposition of those two words seems, well, ominous. Is this the totalitarian government of 1984 taking over? Or the Terminator? Or a little of both?
In truth, state machines are already all around you. All software is fundamentally described by them and I really can't do better than this article to explain what they are and why you - assuming you are a developer - should be very interested.
Personally I am very interested in state machines. I believe they are the best way to write intelligible code that aligns to how we, as software creators, actually think about the solutions we are developing.
The problem is, the programming languages we use don't have state as a first class entity. Instead they are, most typically, protected data records with privileged libraries attached - aka "object-oriented programming". If "state" is mentioned at all in these languages, it is described as the summation of the values of the data record being shielded from harm by the outside world by the language semantics.
Another contender is "functional programming" languages. Although theoretically joined at the hip with state machines, their mathematical purity of immutability often obscures the very practical and common purpose of most software - to change things.
So if state machines are omnipresent in software but obscured by the languages we work with, how can we use them in our daily lives as developers?
This is exactly the problem I encountered as a young developer in the 90's (ancient history I know) with the advent of the Unified Modeling Language (UML). A key part of the the UML specification was a state machine diagram type (more accurately the Statechart diagram). At first I struggled to understand how to faithfully implement system behavior defined in these model specifications. But, over time, I developed a coding pattern that was easy to understand (at least for me) and repeatable in all of the programming languages I was using.
Eventually I developed a shorthand for expressing this pattern which I now call Frame.
I describe Frame as a textual markdown language for system design. The benefits of Frame are:
- It turns object-oriented classes into state machines in multiple languages (currently 6)
- It creates high-level UML documentation that gives the big picture of what the system does.
- It is a simple textual language (you don't have to draw anything)
- Its syntax is intentionally terse and symbolic for maximum information density and (hopefully) clarity
So Frame makes it easy to create state machines - great. But why is the really useful? Glad you asked.
As stated before (yes I said it), state machines compartmentalize code in a way makes it easy to understand what the software is supposed to be doing at any point. This makes building complex software far more intuitive. For instance, when you are thinking about your house, you think about it as a set of joined spaces you traverse in a constrained way.
That is - I can't simply go from the basement den to the upstairs bath. I first have to leave the den, go up the stairs, go down the hall, and then I can enter the bath. This is the very natural kind of structure state machines impose upon the organization of software and makes it much easier to 1) know how many compartments exist and 2) how they relate to each other.
Ok, ok - I know you are now anxious to use state machines in all your upcoming projects. So show me some Frame!
You're finally old enough so lets shed some light on the subject:
#LampSpec -interface- toggle -machine- $Off |toggle| -> $On ^ $On |>| turnOn() ^ |<| turnOff() ^ |toggle| -> $Off ^ -actions- turnOn turnOff ##
That is - different.
Yes it is and there is a lot to unpack, but that isn't going to happen in this article. Fortunately, you can find lots of detailed information on Frame syntax at https://frame-lang.org, but for fun right now you can play with a demo of the Frame lamp for hours (press Toggle over and over again):
Here we can see how the UML documentation makes it easy to see the compartments at a glance. As there are only two (well, technically three but whose counting), the utility of the state machine for dealing with complexity is minimal. But as you add more states, and then add other system components that interact with them, the utility becomes highly valuable very quickly.
To see the code behind the demo take a look at it in the Framepiler.
I hope this whirlwind introduction to Frame has intrigued you to learn more. If so please consider joining the State Machines Reddit and/or the Art of the State Discord. I would love to talk Frame with you!