Live data from Hacker News

Why Developers Never Use State Machines (2011)

skorks.com

111–120 of 164 posts

Re: Why Developers Never Use State Machines (2011)

#111

I really don't like state machines because if you need to add a new event, each of the states need to be updated to handle that event. If you add a new state, you have to figure out how to handle each of the transitions from other states. So as your states grow, the maintenance on the developer's side grows faster than linear. Additionally, I find that I cannot understand how the program works without actually drawin…

> if you need to add a new event, each of the states need to be updated to handle that event Depends on your formalism. I never use state machines of that form for exactly the reason you say. Rather, each state defines the conditions which cause a transition from it. Receiving an event in a state in which it is not expected (say, an I/O completion in a state which should not have outstanding I/O) is a straight-up har…

This idea of defining a hard error for a transition which makes no sense is a nice way to deal with the OPs problem. You must still explicitly handle the situation, but it minimizes the "unwind/undo" code.

Re: Why Developers Never Use State Machines (2011)

#112
post #78
post #12

Traditional programming languages and imperative thinking don't lend themselves to writing state machines, so its not really that surprising that they're under utilized. Its kind of frustrating constantly reading posts where people shit on functional programm(ers|ing) for being too ivory tower-y or whatever, when its kind of hard not to be when a lot of the older FP guys have spent the last like 20-30 years going "yo…

>the older FP guys have spent the last like 20-30 years going "yo this is dope you guys should really be doing this" and getting largely ignored I've not been ignoring them. I tried at least three different Haskell tutorials and articles explaining how cool it is. The problem was the author would show some code sand say 'see how easy it is to do this, and this, and this!', but I'd look at the code and have no idea wh…

> The problem was the author would show some code sand say 'see how easy it is to do this, and this, and this!', but I'd look at the code and have no idea whatever what it was doing or how it was doing it, and the guide/tutorial wouldn't tell me. After a few tries, I just gave up.

You're better off learning OCaml or F# for a small project or two, honestly. The jump from pure procedural to pure functional is big enough without also dragging in laziness, type classes, and monads.

Re: Why Developers Never Use State Machines (2011)

#113

Earlier quoted context omitted.

No, but if well done, it could be enough for me to say, "I get why this is worth pursuing further." I've had the same experience as the person above: Haskell tutorials seem to say, "Look what I can do!" and not, "See how you can do this?"

Well, after a few tutorials you should have noticed that it's a high-level language with clean syntax and a compiler that produces relatively fast binaries. That's a start. What else were you expecting?

Something that shows me how this is worth spending the time learning, when I could just as easily use another high-level language with clean syntax and a compiler that produces relatively fast binaries - but that are not functional - minus the learning curve.

Re: Why Developers Never Use State Machines (2011)

#114
post #12

Traditional programming languages and imperative thinking don't lend themselves to writing state machines, so its not really that surprising that they're under utilized. Its kind of frustrating constantly reading posts where people shit on functional programm(ers|ing) for being too ivory tower-y or whatever, when its kind of hard not to be when a lot of the older FP guys have spent the last like 20-30 years going "yo…

State machines are still and by far most commonly used in C, where, lo and behold, most low-level and embedded programming is still done. And function pointers make up for pretty much the only fundamentally useful aspect of FPs regarding FSMs which is functions as first-class objects. Everything else pretty much just substitutes one convenience for another. A pretty good case can be made about how the State Pattern m…

> And function pointers make up for pretty much the only fundamentally useful aspect of FPs regarding FSMs which is functions as first-class objects.

I'd argue sums and pattern matching are almost as important given the simplicity of expression.

Re: Why Developers Never Use State Machines (2011)

#115
The biggest source of resistance that I've run into is not with the concept of state machines but with common implementations. Two examples:

* A quarter-century ago I implemented a cluster membership protocol and coordination system as a state machine. This provided great benefits in terms of verifiability, extensibility, etc. but some developers complained while the current state was explicit the history of how we got there was not. Adding a history mechanism helped, but frankly it still wasn't as good as the stack traces we'd had before. While the benefits far outweighed the drawbacks, this drawback was quite real.

* On my current project, a critical component (not dissimilar to the the one in the previous example) was implemented by someone else as a state machine. Besides the fact that the semantics of that state machine are unusual and undocumented, and that this state machine also lacks a history mechanism, developers over the years have been wildly inconsistent about which actions occur on which state transitions and how other information is saved/restored "off to the side" between transitions. The result is worse than spaghetti. It's like a chunky goulash that nobody can digest, which is why we're rewriting that component from scratch.

Based on these experiences, I suggest a few rules for implementing a successful state machine.

* Make sure the state machine is properly documented - what the states mean, what the events mean, how a transition is selected when multiple might apply, etc.

* Make the control flow discoverable by providing a history mechanism.

* Make the data discoverable by capturing all relevant flags and secondary state in a structure that's passed to the code implementing transitions.

* Verify the heck out of your state machine every time it changes. Make sure that every path terminates, using timeout events as needed, and that termination includes proper resource cleanup. If appropriate, verify that multiple concurrent invocations can't race with one another and violate the invariants you've checked within each. This verification is much easier to do with state machines than with other approaches, and you should take advantage of that.

Re: Why Developers Never Use State Machines (2011)

#116

Isn't one component of this that so many people develop for web now? And that HTTP is inherently stateless. That means we have to resort to hacks to store state (databases, cookies) - and like most hacks, those are fragile (such as assuming a single instance of state and then breaking when the user opens another copy of the site in a tab). With the rise of single page apps, there's a more coherent concept of state on…

> That means we have to resort to hacks to store state (databases, cookies) - and like most hacks, those are fragile (such as assuming a single instance of state and then breaking when the user opens another copy of the site in a tab).

In principle, there's nothing fragile about the types of state you describe, but most web frameworks don't impose enough restrictions to ensure this state is used correctly [1].

[1] something like this would work, but it's not the only option: http://cs.brown.edu/~sk/Publications/Papers/Published/mk-int...

Re: Why Developers Never Use State Machines (2011)

#117
One thing formal state machines make difficult is component reuse.

Let's say you have a music playback control component you wish to reuse across a feature rich player, as well as a mini playback controller.

You COULD just use the full state machine to power the mini player, but most of the transitions would be unused. It would be unclear to the next maintainer which aspects were needed for each use case, thus making the state machine brittle.

Instead, you can write an independent playback progress/state class, and reuse it in both players via composition and proper layering of functionality.

By hiding the playback state from the rest of the player and exposing control of it's state via an interface, you've gained functional reuse.

Reapply the same pattern for all components of your players and you'll find that your product is safer to change and easier to understand than if you had built a complicated formal state machine covering all possible music player use cases.

Re: Why Developers Never Use State Machines (2011)

#118
post #78

Earlier quoted context omitted.

>the older FP guys have spent the last like 20-30 years going "yo this is dope you guys should really be doing this" and getting largely ignored I've not been ignoring them. I tried at least three different Haskell tutorials and articles explaining how cool it is. The problem was the author would show some code sand say 'see how easy it is to do this, and this, and this!', but I'd look at the code and have no idea wh…

> The problem was the author would show some code sand say 'see how easy it is to do this, and this, and this!', but I'd look at the code and have no idea whatever what it was doing or how it was doing it, and the guide/tutorial wouldn't tell me. After a few tries, I just gave up. You're better off learning OCaml or F# for a small project or two, honestly. The jump from pure procedural to pure functional is big enoug…

+1 F#, really nice language

Re: Why Developers Never Use State Machines (2011)

#119
post #83
post #78

Earlier quoted context omitted.

>the older FP guys have spent the last like 20-30 years going "yo this is dope you guys should really be doing this" and getting largely ignored I've not been ignoring them. I tried at least three different Haskell tutorials and articles explaining how cool it is. The problem was the author would show some code sand say 'see how easy it is to do this, and this, and this!', but I'd look at the code and have no idea wh…

Heh, very often their problem domain is also an issue. "We're going to write a compiler in our shiny FP language". "We're going to implement a Fourier transform". Nah, thanks, could you show me instead how I can get the Employee record from an XML file, stick it in a PostgreSQL database and also send it down the wire through a REST API as JSON?

you forgot the "oh and requirements will change randomly as you're getting employee record from xml file to etc etc

Re: Why Developers Never Use State Machines (2011)

#120
post #48

State machines are not a first-class concept in most currently popular high-level programming languages, so when you implement one, you're merely adhering to a design pattern. While a design pattern is a perfectly legitimate strategy to organize code, it's a manual exercise with no help from the compiler: it's a workaround for the language of choice not being high-level enough for the concepts you're coding. This is…

In between design patterns and frameworks are the perfectly legitimate solution of libraries, which is the most common approach I've seen.
Post reply on HN