Dog FSM

Learn You Some Erlang for Great Good by MononcQc is a really good alternative to the two canonical Erlang Books Erlang Programming by Francesco Cesarini and Simon Thompson and Programming Erlang: Software for a Concurrent World by Joe Armstrong, especially when you need to jump into the language quickly. It gives you enough knowledge to build upon reading other people’s code, documentation, and coding.

Things taken for granted by Erlang programmers can be confusing to newcomers to concurrent and functional programming. Needless to say, jumping from, say, C# to Ruby is far less adventurous than from any of the two to Erlang. While reading the book I found out that readability of certain pages could be greatly improved by a few more code examples, and I spent time in the Erlang shell and my editor writing additional code to better undertand the concepts.

I did actually write an email to MononcQc with a few lines of code, and his reaction was positive, but the guy seems to be really busy at this moment to make any changes to his book, so in the meantime I am going to post code extracts here in my blog hoping that it will save a few brain cycles of future readers of the book.

The first example is for page Rage Against The Finite-State Machines . In this page the author first gives two examples of Finite-State Machines written in plain Erlang, an FSM for a cat, and an FSM for a dog. Then the author explains the API of gen_fsm, and right after that he goes on implementing a complex (at least for newbies) trading system with two FSM processes talking to each other and to their clients. 450 LOC together with the tests.

Hmm… There is something missing between the super simple naïve examples not using any APIs and then the complex stuff using gen_fsm. Namely, a rewrite of these two primitive FSMs with the use of gen_fsm. This way by the time the reader starts struggling through the complex part he would have already seen the gen_fsm API in practice. One thing less to learn at once.

Here goes the dog_fsm example:

Let’s run it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2> c(dog_fsm).    
{ok,dog_fsm}
3> dog_fsm:test().
<0.41.0>
Dog says: BARK! BARK!
Dog says: BARK! BARK!
Dog wags its tail
Dog is sitting. Gooooood boy!
Dog is confused
Dog says: BARK! BARK!
Dog says: BARK! BARK!
Dog says: BARK! BARK!
Dog wags its tail
Dog says: BARK! BARK!
Dog says: BARK! BARK!
Dog wags its tail
Dog is sitting. Gooooood boy!
terminating with reason normal at state sit
4>

Notice the usage of gen_fsm:send_event_after to implement a transitions on a timeout, and the way the timers get cancelled if another event arrives. If the timer is not cancelled, the timeout event will be triggered at another state, not something we want to use it for.

Voila.

Happy erlanging!