Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2008-08-17 15:30:22


on Sun Aug 17 2008, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:

> David Abrahams wrote:
>> on Sat Aug 16 2008, "Christian Holmquist" <c.holmquist-AT-gmail.com> wrote:
>>
>>> Sorry for breaking in, I'm no expert on state machines at all but.. isn't
>>> the goal of expressing a FSM by the aid of the proposed to library to
>>> minimize the chance of undefined behaviour?
>>
>> *The* goal? There are lots of potential reasons one might want to use a
>> library. In general, a library that allows a fairly direct expression
>> of the FSM as described in its "native" language (OK, maybe graph
>> diagrams won't work, but you could use state transition tables) should
>> lead to code that is more correct and maintainable.
>
> David, you won't argue that every tool has its purpose, will you?

?? I wouldn't waste my time making that argument since it is a bit
tautological.

> I'm sure it is possible to put a nail in the wall with a microscope,
> but it's not the microscope's flaw that it's too fragile for
> that.

Sorry, I don't see your point. I was just saying that there is more than
one good reason why someone should use an FSM library, and no single
reason has greater absolute importance.

> State machines, as I see it, are meant to define an object behavior,
> IOW reduce the amount of undefined behavior. It is pointless to use
> them to implement undefined behavior.

So std::vector is pointless because it exhibits undefined behavior when
misused? There are at least two good reasons for allowing the result of
certain operations to be undefined:

  1. There's no way of checking that the input is valid. If someone
  hands you an invalid pointer there's not much you can do about it.

  2. Efficiency. Checking that the input is valid would slow your
  application down.

>> I find the code written using the proposed library rather procedural
>> in nature (rather than declarative), thus the OP's comparison is very
>> apt from my point-of-view. The hand-rolled code actually looks
>> clearer and more direct to me.
>
> Please, have a look at my reply to Phil. I've attached a code snippet
> with a transition map. Does that look more declarative?

Not really, to me. It's very difficult for me to see the transitions in
that code. Compare that with either of my player examples.

IMO, a good FSM library should present the FSM such that it's easy to
see the machine's structure, preferably in a form that is *already* used
to describe FSMs, outside of code, such as a state diagram. It would be
great if we could embed the state diagram in our code, but C++ doesn't
do that. You have to leave that level of abstract expressiveness to GUI
tools that generate code. My code uses the "state transition table"
abstraction instead, which seems to be about the best we can hope for in
straight C++.

>>> If the OP's state machine doesn't guarantee its valid state,
>>
>> It guarantees a valid state as long as the inputs are valid, just as
>>
>> x / y
>>
>> or
>>
>> *p
>>
>> do, where x, y, and p are primitive types. Most libraries I know have
>> similar contracts.
>
> I don't fully agree with this. On the one hand, yes, most libraries rely
> on the valid input and this is "the right thing". On the other hand,
> FSMs are often used in domains where input is not always valid (parsers,
> protocol clients, GUI and so on).

Yes, a generalized FSM library should offer strong guarantees. The OP
was building a specialized FSM from scratch. For any particular domain,
the choice to allow undefined behavior may be appropriate (though I
doubt USB is such a domain).

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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