

Generic FSMs in Erlang - keyist
http://learnyousomeerlang.com/finite-state-machines

======
chunkbot
Good stuff. Compared to the more "popular" generic behaviours like gen_server,
gen_fsm doesn't get a lot of attention. It's nice to see it added to your
tutorial with this level of detail.

~~~
jerf
I've also gotten good mileage out of "gen_event"; I have a protocol with a
generic connection layer, then a modular part where you claim you support
"Module X", which is implemented as a gen_event plugin that first verifies you
can do that, then allows this connection to have that module. It makes it
really easy to write something relatively secure by ensuring you can get to
certain capabilities if and only if you pass a certain check to validate you
ability to have them. It's a good tradeoff between typing (as in, typing
things on the keyboard) and security for me.

------
mononcqc
Author, here. I hope you enjoy.

~~~
pivo
Thanks, I am enjoying it. I'm working on a holiday project that includes
writing an Erlang server that will need a FSM. Even though I've written many
FSMs in other languages I'm new to Erlang, so it's great to have this nice
guide. Glad I decided to peruse Hacker News before I started on the FSM
implementation!

------
burgerbrain
I prefer name-brand flying spaghetti monsters actually.

~~~
code_duck
That what was I thought when I saw the title, too. However, from experience I
realized that making any sort of comment alluding that without adding
substantively to the discussion would certainly elicit sanctimonious shows of
disapproval.

The key to getting away with that in this topic would be to make an insightful
comment about finite state machines, and throw the FSM reference in at the
beginning or the end. Extra bonus if you can skillfully weave a Flying
Spaghetti Monster narrative into your comment, like a parable.

------
nivertech
Too bad the new "Erlang and OTP in Action" book leaves gen_fsm out of scope.

Anyway gen_fsm behavior is pretty weak comparing to FSM frameworks I used in
C++: no on_entry / on_exit callbacks.

Also, I'm not sure you can use gen_fsm sequentially by itself (i.e. without
Erlang process).

~~~
jerf
"no on_entry / on_exit callbacks."

That's not too hard to fix; write your handle_event callback as something that
observes the state, dispatches out to the "really_handle_event" function,
observes the new state, and fires the desired callback, implemented however
you want them to be. Ten reusable lines or so.

"Also, I'm not sure you can use gen_fsm sequentially by itself (i.e. without
Erlang process)."

Not really much point, really. The gen_fsm itself is basically wrapping the
state machine described there into a supervisor tree. If you don't want the
supervisor tree, it is utterly trivial to write a state machine of your own in
Erlang. It is one place where pattern matching excels. You want some sort of
record indicating your state, then you can do things like:

    
    
      -record(state, {name, val1, val2}).
    
      event1(State=#state{name = initial}) -> handle...
      event1(State=#state{name = connecting}) -> handle...
      event1(State=#state{name = connected}) -> handle...
    
      event2(State=#state{name = initial}) -> handle...
    

and so on. A little more plumbing is necessary to manage returning the new
state but that's the basic idea, which is just about the only other thing you
"get" from gen_fsm "for free".

~~~
nivertech
As Erlang is Turing-complete, obviously you can code FSM in it. The question
is, giving Erlang/OTP Soft-Realtime Telecom roots, why FSM primitives are so
weak?

From a good FSM library I would expect following:

    
    
      1. Specify human readable STT (State Transition Table)
      2. For each event/state combination specify if it's valid or should be ignored, etc.
      3. On entry / on exit for each state.
      4. Masking/unmasking of events.
    

gen_fsm as it today do not provide much value over gen_server.

------
kungfooguru
Great stuff. I was just arguing on the ErlangCamp mailing list that the
gen_fsm behaviour is great! I just sent this out to everyone.

