
Why Developers Never Use State Machines - fogus
http://www.skorks.com/2011/09/why-developers-never-use-state-machines/
======
patio11
I use them extensively for Appointment Reminder. In addition to modeling the
business logic pretty intuitively (particular types of input can cause an
appointment to go from :scheduled to :confirmed, :confirmed appointments
should not generate additional reminder calls but :scheduled ones should,
etc), they're virtually indispensable for doing Twilio applications. I'll have
more to say about that at TwilioConf (and will probably post my presentation
afterwards). If you do not model call state with a state machine, anything
more complicated than "Hit 1 to talk to sales, hit 2 to talk to support" turns
into an ugly ball of spaghetti code with lots of sharp edges, poor
testability, and crushing amounts of technical debt getting in the way of
maintaining or extending anything.

After I got more comfortable with actually using them for real work (as
opposed to "cute toy from CS class"), I started seeing FSMs everywhere I
looked in my projects.

For one thing, they make analytics a _lot_ easier to slot into your system.
For example, I record the fact of interesting events like e.g. purchases and
send it off to KissMetrics or internal analytics stuff for
graphing/reporting/auditing/etc. That gets done in my controllers, and it
results in a whole lot of duplicative code which I often forget to write.
(It's easy to miss that e.g. if I credit somebody manually for a purchase that
should count as a purchase, even though it is under admin functions rather
than the purchasing pathway. After all, if I forget to write that log code,
all that happens is my stats get silently borked.)

This could get fairly easily solved by having the logging code aware of the
change in the user's status, which is about three lines if you have a state
machine, and won't put the logging logic in 12 different places in your app or
cause you to have to pollute the user model with a big ol' case statement of
doom. Plus, if you want to log more stuff, you naturally go into the log logic
and make it do more things when the right events bubble to it, rather than
chasing down a) who "owns" the event or b) where the event happens.

~~~
smanek
I found it more useful to control my Twillio interaction via a Finite State
Transducer (FST - <http://en.wikipedia.org/wiki/Finite_state_transducer>)
instead of a FSM.

An FST allows you to accurately model 'outputs' on state transitions (where
those outputs can be side-effects like 'make a call' or 'send an invoice.'
This allows you to prove things about what sort of side-effects/outputs will
necessarily have occurred by the time the FST is in a certain state.

I started with an FSM but, found in practice, I was using it like a poorly
written FST.

~~~
nourishingvoid
FST's are used a lot in natural language processing, for example in speech
recognition and dialogue systems. In these cases the state transitions are
given probabilities (weights), which makes it a weighted FST.

Sometimes I used FSM's during the design phase of a project to model system
behavior, but I'd end up implementing them pretty crudely with spaghetti code
or case statements. Looking back, it would have made more sense to explicitly
implement the FSM in the code.

------
tseabrooks
Pretty much every embedded system used for a consumer electronics device is
driven by a state-machine. They are really fairly fundamental to embedded
development. I suspect this guy is talking about (and dealing with) mostly web
developers and people who don't sit so close to the metal.

In my current position it's entirely expected and reasonable to write some
code and then half way through go back and rip parts of it out and turn it
into a statemachine. Though generally we produce fairly detailed designs of
our SMs first.

~~~
Fluxx
The act of going back over previously written code that is headed down the
wrong path to refactor it to be more flexible/modular before you write your
next feature with that code is almost always worth it. It's _not_ worth it if
you're never going to extend this feature ever again, but chances are, if
you're revisiting a feature right now you'll revisit it again later.

------
fab13n
Having used state machines a lot for embedded development, I find that they
have one huge drawback: the resulting C code is unreadable, which turns
maintenance into a nightmare.

SM have a key quality: they are a compact and unambiguous way for specifying a
behavior. If your system's behavior is set in stone, it's worth specifying it
as a SM and implementing it as one. This SM is also great to include in a
spec, standard, RFC etc. But if the system evolves, small changes can require
dramatic reshaping of the machine.

Also, they can lead to very efficient implementations, especially if you don't
have the benefits of a serious OS with a fancy scheduler underneath.

~~~
ajross
Amen. I think the only reason state machines are popular in microcontroller
work (not really "embedded" -- big SoC software looks like desktop software)
is that they're a common _hardware_ implementation choice. And most of those
uC programmers are EE cast offs who look to hardware for their reference of
taste and not "software engineering".

So they suck in a bad implementation choice because it looks pretty to them.
Not so different than the way most Java development works, honestly.

~~~
snikolov
_So they suck in a bad implementation choice because it looks pretty to them_

An implementation choice that looks pretty is often a good implementation
choice.

~~~
ajross
Except, as I was careful to point out, when it's bad. I hoped my example was
useful: people think the OO hell ("class Point", "class Length", ...) in Java
is "pretty" too. Aesthetics are squishy. It's easy to point to great code and
infer that it's beautiful to other great coders.

But that doesn't change the fact that most people have pretty awful taste. The
affinity of uC hackers to state machines, IMHO, is a good example of this.

------
mmahemoff
State machines are a form of declarative logic as opposed to procedural, and
declarative is often superior for modelling real-world activity.

Procedural logic tends to be brittle - small changes have unintended
consequences. Declarative models tend to be more robust and, especially with
domain-specific languages, safer for domain experts to manipulate. You can
certainly design domain-specific languages for the subset of declarative
systems that are state machines.

I've happily used state machines in enterprise projects. One was tracking
rates of financial instruments, where they would be in various states of
validity (i.e. is it a live offer?). Another was a logistics app, where data
would move through various states of being cleansed and approved, or rejected.
We built a UI around it. By isolating the state definitions and their
transitions, it was easy to validate the program's model with business exprts.

------
JoeAltmaier
Use them all the time, have for all my career.

They organize complex code, dissect complex set-flag-here-and-test-there
spaghetti into a matrix of states and events that can be exhaustively examined
and debugged.

Yes you have to organize your code to feed the machine (Vol is hungry! We must
feed Vol!) But you have to organize your code somehow, and feeding a state
machine can actually be easier to understand that flag-setting. In fact, it
makes it absolutely clear what an event is associated with - the machine it
feeds.

~~~
moondowner
True, it's better to have a set of states instead of a dozen boolean values.
It gives better code, and better organized databases too.

------
mas644
State machines are useful because they're 1) computationally fast 2) simple to
implement 3) easy to read [up to a certain size]

The big problem with state machines relates to the number 3 and regards the
general concept of "state". Managing state is the challenge of computation! As
you add states and transitions, the complexity increases dramatically,
exponentially in some cases. This is why novice programmers struggle to manage
developing large applications: they depend on global state and side-effects to
perform computation rather than creating isolated components (classes,
methods/functions)

That is why we use higher level abstractions provided by programming
languages. We use state machines unknowingly in our code every time we have a
switch or a conditional statement. When we use design patterns such as the GoF
state pattern, we are implementing a state machine. When we build closures in
functional languages, those can be considered state machines (in an abstract
way). It's just that we're doing it in a more intuitive, higher-level way.

What I'm getting at is that computer programs inherently contain state
machines. Recall from computer science that a a stored program computer (e.g.
Turing machine, Von Neumann architecture) is just a state machine with an
unlimited memory. When we deal with more complexity, it's not wise to attempt
to model the problem with a state machine. Using the constructs of a high
level language are easier to deal with and underneath the hood, the
appropriate state machines are being created.

~~~
Roboprog
Good points. Sometimes it's nice to be able to visualize an explicit directed
graph of states (vertices) and events (edges), though. It helps identify
inescapable states and unhandled events.

------
super_mario
Simple, because most developers are not computer scientists i.e. no formal
training in finite automata, computability, complexity, nondeterminism,
regular expressions, non regular languages, context free grammars and
languages, Turing machines, halting problem and underlying math in general.

If they did, trust me they would use state machines without too much
reservation where appropriate. But as it is, the concept is foreign to most
and good ones intuit their way into implementing one perhaps (just guessing
here).

~~~
Nelson69
Couldn't you just say: all developers use state machines, some just aren't
sophisticated enough to know it?

I'd even say that today, most developers use fairly explicitly defined state
machines (like there is even a code entity called "state machine" somewhere.)
Every time they fire up a regular expression.

~~~
cbs
>most developers use fairly explicitly defined state machines [...] Every time
they fire up a regular expression

They're not using state machines, in that case it just happens to be an
implementation detail of the regular expression library they're using.

------
moondowner
I (as a Java developer) use state machines often - and know other developers
who do same too. I use mostly enums (though there are other ways of achieving
it), as explained in this post:

Java Secret: Using an enum to build a State machine:
[http://vanillajava.blogspot.com/2011/06/java-secret-using-
en...](http://vanillajava.blogspot.com/2011/06/java-secret-using-enum-as-
state-machine.html)

------
masklinn
It's used a lot in Erlang, FWIW. It's used so much that OTP has a built-in
finite state machine behavior[0].

Of course having nicely isolated processes probably helps noticing that you
have an ad-hoc state machine on your hands.

[0] <http://www.erlang.org/doc/design_principles/fsm.html>

------
bchallenor
The Rust language (by Mozilla) is putting statically verifiable state machines
in the type system:

<http://lambda-the-ultimate.org/node/4009>

It's based on Typestate, a really good 1986 paper:

[http://www.cs.cmu.edu/~aldrich/papers/classic/tse12-typestat...](http://www.cs.cmu.edu/~aldrich/papers/classic/tse12-typestate.pdf)

I hope this idea catches on in other programming languages.

------
conductor
If you are a C developer, try Ragel [<http://www.complang.org/ragel>]. I use
it lot, also can be easily pared with the Lemon parser generator.

~~~
tom_b
For more re: Ragel, look at

<http://zedshaw.com/essays/ragel_state_charts.html>

What I really like there is the idea of a DSL that generates your state
machine code for a protocol.

------
ender7
Can anyone recommend a good introduction to using state machines in code?
Especially something in javascript/python? I know what an SM is and how it
works, I just want to know how to use an SM library to actually do all these
cool things.

~~~
pasbesoin
A lot of the IBM Developer articles are apparently crap, but I found this one
interesting and well done, some years ago.

The article date looks different, now, and IBM has redesigned the site since I
originally read it, but I think -- at a glance -- that it's the same article.

<http://www.ibm.com/developerworks/library/wa-finitemach1/>

[http://www.ibm.com/developerworks/web/library/wa-
finitemach2...](http://www.ibm.com/developerworks/web/library/wa-finitemach2/)

[http://www.ibm.com/developerworks/web/library/wa-
finitemach3...](http://www.ibm.com/developerworks/web/library/wa-
finitemach3/index.html)

~~~
rhizome
I have to think that somewhere around 2007 IBM started offering massive
bonuses for writing site content and HOWTOs.

~~~
pasbesoin
Your reply motivated me to look, and my vague recollection is correct: I
exchanged a couple of brief emails with the author back in 2007, when the
articles did indeed first come out.

However IBM did it, they were entered into some sort of site publishing
schedule such that he'd lost track of just when they were coming out.

Seemed a nice enough fellow. From the articles and his bio, I imagine (perhaps
incorrectly) his motivation was more pedagogical than remunerative.

------
wccrawford
Upon reading this, I realized I had never really looked into state machines
much. In my searching, I found a Coffeescript state machine that has a nice
chess-based example:

<https://github.com/stephenb/coffee-machine>

------
splicer
FSMs are _very_ common on the embedded systems I work on. In fact, I often
find that my coworkers use them too much. For instance, sometimes a DSP filter
would be a much cleaner and maintainable solution. That said, if you work on
embedded systems and you've _never_ used a FSM, you're probably doing it wrong
;)

------
davedx
This man has never heard of video game A.I. programming :)

~~~
pagekalisedown
I had the same reaction. Almost nothing but FSMs in game AI. Makes me wonder
if we need to look beyond FSMs for the next level of intelligence.

~~~
RodgerTheGreat
The natural next step is a PDA. Perhaps you could use this type of system to
model an AI that can get distracted or become faced with an intermediate task
and then return later to the original objective?

~~~
tomjen3
For those of you who don't know what a PDA (Push Down Automaton) is, it is
basically a standard finite automaton but with a stack that you can push
things to and pop things of -- you can then react differently if you get input
a in state B versus getting input a in state Q.

Many parsers make use of PDAs when they parse source code.

------
perfunctory
I never understood why one needs a framework or a library for state machines.
Can't you just write a switch statement.

~~~
marshray
Yes, but sometimes you need logic that takes place on all exits from a state,
on all entries to a state, or even form a hierarchy of nested state. Often
there's more "state" involved (like accumulating intermediate values) and a
switch statement isn't friendly to scoping that.

I love writing switch statements (even with gotos) for small things like
lexical analyzers, but when it comes to maintainability and extensibility, a
well-designed framework is the way to go.

The Boost C++ libraries supply two of them. I've used one of them and am eying
the other. They claim its template magic can make the result actually faster
than a typical switch-driven design.

------
kennu
I've always used a state machine whenever I've parsed XML using an event based
parser (SAX).

Although lately I've been replacing an explicit state variable with a stack
containing the current element path, since that's pretty easy to do using
modern languages.

~~~
caf
Parsing textual formats in general usually ends up being a state machine - eg.
CSV is another one.

------
Maro
I spent the last 3 years writing a distributed database which is basically a
state machine (it's built on top of Paxos).

<http://github.com/scalien/scaliendb>

------
wslh
State Machines are also useful when you need to develop on asynchronous
environments but think in a more synchronous way.

------
erikb
Not sure if I understand the author correctly, but it seems to me, that he
advises to write the state machine behaviour down as code (in form of a class?
api? little frameowork?) when you start a project, so that you will be able to
use a cleanly written interface for your state machine when the project gets
bigger. Is my understanding correct?

From my experience a state machine is more of a pattern then a real object.
Implementing it on the fly is what worked best so far, for me. Of course there
is a point where it gets nasty because of complexity. But first that is always
the case (complexity IS nasty) and second overcommiting to structure and
architecture increases the complexity already in the beginning and might hurt
more then it helps. At least fully coding all possible state machine behaviour
as the first default task ifor every new project doesn't seem to be a smart
thing to do.

------
relix
I discovered how state machines can be practical when checking the source code
of Spree, the rails e-commerce engine. The checkout-process is a state
machine.

I'd highly recommend using state machines for multi-step forms. It feels very
natural and keeps you sane, I believe it should be a best practice.

~~~
IProgrammer
>I'd highly recommend using state machines for multi-step forms. It feels very
natural and keeps you sane, I believe it should be a best practice.

That's interesting. Can you elaborate on it, maybe with an example?

~~~
relix
Basically each step in your form is a state in the state machine. When a user
submits one step, you move the state machine to the next state. You can add
conditionals for when to skip a step, and you can specify validations for each
step that need to be run before a state-change (e.g. credit card needs to
check out before moving from the credit card step to the confirm step).

You can check out Spree's state machine for the checkout process here:
[https://github.com/spree/spree/blob/master/core/app/models/o...](https://github.com/spree/spree/blob/master/core/app/models/order.rb)
(starts at line 83). Notice that the Order model _is_ the state machine.

------
foobarbazoo
SproutCore has an entire statechart framework built into it. Not sure where
the OP is getting his data...

------
phamilton
While I don't use state machines in code that often, I do use them on paper
all the time.

------
signa11
anybody writing networking-protocol code, embedded systems etc. cannot help
but use them. to me it seems that the entire article is pretty narrowly
focussed on folks doing web development exclusively.

also, fwiw, i think, couroutines are to state-machines as subroutines are to
goto. the best tutorial on teh web on this is, imho, by dave-beazley here:
<http://www.dabeaz.com/coroutines/index.html>

------
KevinMS
Mail servers are state machines. The SMTP protocol is all about state.

In a way any web app with a login is also a state machine - there's the logged
in state, and the not logged in state.

erlang has a very effective state machine library(behavior). But the downside
is that it's erlang. <http://www.erlang.org/doc/design_principles/fsm.html>

------
hessenwolf
I think in state machines all the time, and I have it second hand that
telecoms services in South America mostly run on state machines.

------
philgo20
We use FSM to deal with the hiring/applicant flow at <http://matchfwd.com>

FSM are very common in video games. I've also worked with one in a (very very)
big engineering/CAD software when FSM was managing the whole
approval/review/audit flow .

It seems there just less common with web dev in general.

------
radicalbyte
They're used all the time. A workflow engine is basically a big state machine.
They're used all the time in the Enterprise.

In object orientated software engineering the State pattern is a pattern for
cleanly implementing a state machine* whilst avoiding horrible switch or
massive nested if-then statements.

------
UrLicht
I _didn't_ get a CS degree and therefore had no experience with state machines
until I started programming professionally. Maybe that's why I took to them so
quickly and used them from the get-go on my personal project. Their usefulness
is so obvious.

------
pnathan
I don't understand the problem. State machines always seemed like a reasonable
choice to a stateful system making transitions between states.

It's possible to build some gorgeous state machine networks with lambda
functions and dictionaries.

------
whatgoodisaroad
I literally just finished writing a state machine before opening Hacker News.

------
bmcleod
I've been adding a state machine whenever I find myself adding a state column
for a couple of years now.

I have always found this streamlining at least one change in the couple of
months after initial implementation.

------
gte910h
There are over 10 occasions I can _remember_ using one specifically in a
project. I'm sure I've used them several more times.

Then again, I think they're far more common in the embedded world than
elsewhere.

------
probablyrobots
I agree with the discussion here. State machines are very useful. The best
thing about them is how easy they makes documentation. You just draw a state
diagram and you're done!

------
alanh
This article inspired me to go ahead and actually use a state machine for what
I’ve been working on. I love the resulting clarity in my code. ❤

------
cpeterso
_"A Computer is a state machine. Threads are for people who can't program
state machines."_ \-- Alan Cox

------
nkh
Can anyone recommend a good python library for state machines and example code
of its use?

------
swah
Do you guys think a drawing program should be more easily modeled with a FSM?

------
schiptsov
guess what is nginx? ^_^

------
CPlatypus
I disagree with the author; most developers' attitudes toward state machines
are poisoned not by academic experience but by experience with other
developers' half-assed state machines. Back in '93 or so I used state machines
extensively for protocol handling within HACMP's cluster manager. It worked
very well, but there were still complaints which all came down to the broken-
up control flow that state machines introduce:

* The code can be harder to understand, even for those accustomed to the model, because of the need to maintain context manually across states and events. Let's face it: having your variables on the stack is awfully convenient, even if there are good reasons not to do things that way.

* Speaking of stacks, the #1 complaint I used to get was that with the FSM stack traces would only go back to the FSM engine with no history of previous transitions. This is why IMO any decent FSM implementation _must_ keep some history itself.

* A related issue is that static code analysis can't follow through the transition table to recognize the actual flows of control. A good FSM-based program must therefore include stub programs (which can be automatically generated) which will invoke actions in expected sequences so that code checkers can find invalid references, leaks, missing unlocks, and son on.

I like FSMs and think they should be used more. Nonetheless, if you gave me a
state machine with ad hoc context management, no history and no reasonable way
to generate test stubs, I'd barf too. If more people implemented _good_ state
machines, more people would recognize their benefits.

------
pointyhat
In my experience, why "developers" never use state machines:

a) Most I speak to had a Z-rate CS education which scraped a bit of OO design
in Java and don't know they really exist.

b) Most languages they cut their first code in are about puking data around
from SQL to the web which rarely if ever requires an FSM.

c) Someone thumped them over the head with "Windows Workflow for dummies"
which is then assumed to be the answer to all stateful problems.

d) It looks hard so they don't bother.

e) "developers" should not be confused with "computer scientists". It's
"builders" versus "engineers".

~~~
cbs
Unfortunately for our industry, a lot of your post is right, and it doesn't
just apply to state machines, but a lot of solid programming practices.

------
sid0
_most state machines you're likely to need in your day-to-day development have
nothing in common with their computing theory counterparts_

I don't follow this? The core of whichever state machines I write seem to be
DFAs, with the alphabet being events causing transitions.

~~~
amouat
I think the point is that you don't need to know all the dry theory and the
names for everything.

------
oinksoft
I think the author should bold, quote, and italicize more phrases.

------
albertzeyer
This is a stupid statement. Pretty much every code depends on a state (i.e.
the content of the heap memory) and is thus a state machine (by its most
generic definition).

I think he is referring mostly to a finite state machine, though. But even
then, you have that quite often somehow in your code (think of global boolean
variables).

~~~
marshray
Well the memory available to the processor for state is finite, too. Thus,
every classical computer is a finite state machine.

That said, some programs have state that is more finite than others. :-) Deep
down, a "state machine-based design" is a mindset of the designer.

~~~
deepinit_a
Well said!

