Hacker News new | past | comments | ask | show | jobs | submit login

All of these problems are solvable if you apply a bit of DRY, and use better languages. I would despair of trying to combine state machines and DRY without closures.

The final remaining "hard to read" that remains after DRY is usually a reflection of the problem domain, not the solution domain. That's a barrier you can't pass through; if you got seven states and ten events, you've got seventy things to deal with, one way or another. (Which doesn't have to mean 70 literal handlers, but does usually mean still quite a number.)




Indeed. If you do not use a state machine in a situation like that, you either get very complicated code as well, or you conveniently do not implement some of the state transitions. That will always get back to you: "how can this ever happen?!"

State machines force you to consider all possible state transitions. This makes sure that transitions are handled properly, or they are actively made impossible.


I reduced a buggy, crashing, network protocol (serial modem!) to a state machine (three actually) in 2 days; had it debugged in another few days and it chugged along like a workhorse for years.

In the process all the bugs in the original code were revealed - literally a hundred cases unhandled or incompletely handled. The code I found had a dozen flags and enourmous runon procedures at every event entry point, totally unreadable.

SO yes I am a keen fan of state machines. But I admit they dominate your code architecture and look funky. Closures are definitely a good thing, tho I haven't yet figured out the best pattern. Its good to have all the cases laid out in front of you, with each combination of state and event commented and discussed. What would that look like using closures?


"It depends." Whether you should show every combo of state and event or not is a local decision. What closures really make easy is something like "I always set something up, do something, and tear it down", and it allows you to put the set up and teardown in one place. Or maybe it lets you put the "something" in one place and it's the setup and tear down that are different every time. Or maybe you've got multiple state machines that are talking to each other, and it makes it possible to abstract them from each other a bit. It isn't like there's one design that they enable that is impossible without them, it's more like, it's a tool without which I would really be stuck.

But one concrete example: I have a state machine that manages connection to a network resource that requires a negotiation process. I have some code that would like to just use that connection, without having to manage it, and there are many ways to enter this code and many things it may want to do. During the connection process, if more requests come in, the connection state machine just stacks them up as closures to be executed when the machine completes its connection. (Or, called another way, notify the callers of an error.) These closures themselves contain other ones that have the details of how to back to their state machines and send a message along that particular socket to go back out to the right client along one of several protocols. None of this is impossible without closures, but keeping the machines ignorant of how the other machines work is a lot harder without them.

OO can do it too, albeit with a different flavor. Without one of OO or closures is a pain, though.


would love to see a blog post glancing at the 'before' code and overviewing the 'after' code. Even if it was just two pastes.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: