But this bit resonated with me very strongly:
> is unfortunate that the majority of the ma- terial written on reducing finite state automata to code is in texts on compiler construction. Finite state machines play a sufficiently impor- tant role in a variety of computing applications to suggest that their use in programs should be introduced in lower level or even introductory programming texts.
So many things are better modeled as state machines, and their use as a programming pattern is rarely taught / seen in the wild.
not sure the goto approach would much better but this approach ends up just being a poor reinvention of goto in java
You don't want to mix the FSM with the internals of the states. For example:
result = state1.action();
if result == A THEN GOTO STATE_2
if result == B THEN GOTO STATE_7
Is okay. Complex internal logic is not:
[ton of actions and logic]
if [ton of logic] THEN GOTO STATE_2
if [ton of logic] THEN GOTO STATE_7
If your states are more complex than that, it's a mess. Or if your language supports it:
NEXT_STATE = state1.action()
Again, modern language support is horrible for this sort of thing.
You can go one step up and make a generic FSM, with e.g. a Python dictionary of functions which return future states:
state = STATES[state.action()]
FSMs can work really well for software, but perhaps the complexity of a program would result in a massive number of states. I have also found it is harder to reason about the entire operation of a FSM.
The loop based implementation also seems more similar to how one would implement an fsm in a hardware description language. A loop that is visited once per clock cycle seems easier to understand and debug.