Boost logo

Boost :

Subject: Re: [boost] [MSM] Comparison with ad-hoc FSM implementation
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2009-12-10 05:54:24


Hi,

Michael Caisse wrote:

>This concept is difficult (messy) to implement with ad-hoc techniques.
>I personally find that the richness provided by some of the modeling
>language constructs produces very simple solutions for what can often
>be messy problems to solve. It brings an elegance to the solution
>space that cannot be found in just states and transitions alone.
>It is the richness of the modeling language that helps one solve more
>complex problems without complexity.
>
>Sure, in these simple toy examples the ad-hoc switch statement looks
>as good if not better than a complex library. But as soon as we start
>making something that is industrial proof with all the error cases
>and whatnots ... well things start getting more complicated and
>I personally start looking for some additional constructs to help out.

I fully agree with Michael's point that more complicated constructs
are really messy to implement with ad-hoc techniques. And the real
power behind a fsm library is the abstraction from code to move on to
higher abstractions.

But on the construct presented by Phil I personally find a lot to criticize.
First of all, it is a mess. The code is long and even while the
machine is so trivial that you could almost do it without a fsm, it
must be quite hard to follow if one adds all what was left out for
demonstration purposes.
Second, and what really bugs me is the mix of fsm structure with
character processing. Such a code is not to be reused (if one doesn't
count a selective copy/paste).
This is made even worse by the fact that this is obviously GUI code
and such processing must happen several times in different modules.
I also don't like:

>void process_event(const character_received_event& e) { ....
>void process_event(const sigwinch_event& e) { ....

Having to write overloads in a template word??? No, thanks!

I think the only thing I like in it is the O(1).

Phil Endecott wrote:
>How would you do this with MSM? Something like this presumably:
>
>row < normal, character_received_event, seen_escape, none, &is_escape_char >,
>row < normal, character_received_event, normal, &insert_at_cursor_and_advance >,
>row < seen_escape, character_received_event, normal, &cursor_home, &is_H >,
>row < seen_escape, character_received_event, normal, none >,
>row < any, sigwinch_event, unchanged, &resize_screen >

Apart from the fsm structure and syntax errors, which are irrelevant
to the discussion, yes, I could do something like this if performance
were uncritical in this part of the application and I wanted a chance
to play with eUML. But more likely, I wouldn't do that.
Instead, if performance was an issue I'd probably keep the second
switch/case (the switch on character), pack it inside a nice generic
functor which would in no case do this:

>case escape: state = seen_escape; break;

Because this means mixing character processing with fsm structure.
It'd be something like (as entry functor. Could be as transition functor too):
struct CharTypeProcessing: euml_action<CharTypeProcessing>
{
    template <class Event,class FSM,class STATE>
    void operator()(Event const&,FSM& fsm,STATE& )
    {
        switch (c) {
          case escape: fsm.process_event(escape_char()); break;
          .... more special characters like tab, newline etc ....
          default: fsm.process_event(normal_char(c) ) ;break;
        }
    }
};

I don't go more into details but I'm sure you get the idea. We now
have a generic functor, which can be reused in any state or fsm
without any knowledge of the structure. It can be documented as:
name: CharTypeProcessing
description: checks for special characters. Triggers event
normal_char(char value) if a normal char, escape_char if escape, etc.

And now, any other developer can reuse it, without having to dig into
the code to get the part he needs.

But what really really strikes me is that it's already Phil's second
implementation of a fsm on 2 examples. And a pretty different one than
the first! This means double work, double debugging. Add this to the
fact that the character processing is also not reusable (mixed with
fsm structure, as we saw) and I think I'll be enjoying a latte with a
choco-croissant (my favorite) while other developers will still try to
find why Phil's code doesn't work for them (hint: they surely made a
mistake in their copy/paste. Tsss...).

>You are welcome to try to
>convince me that it has benefits that I have not yet seen....

Sorry but I won't try because I doubt, from experience, that someone
who will have spent a long time on his multiple switch/case will want
to give up this work too fast. But it's really ok for me, as I said, I
wrote MSM for people like me, who can't see a double switch/case
without a strong uncomfortable feeling.
If you feel more comfortable with it, great for you! Only, if you ever
look for a copy/paste error for hours, I hope you'll picture me with
my latte and choco-croissant and switch back to MSM. I'll be happy to
share a latte with you ;-)

Regards,

Christophe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk