Boost logo

Boost :

Subject: Re: [boost] [MSM] Is there any interest in C++14 Boost.MSM-eUML like library which compiles up to 60x quicker whilst being a slightly faster too?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2016-02-11 07:28:02

Le 10/02/2016 22:07, Krzysztof Jusiak a écrit :
> On Wed, Feb 10, 2016 at 5:11 PM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>> Le 10/02/2016 11:51, Krzysztof Jusiak a écrit :
>>> On Tue, Feb 9, 2016 at 11:00 PM, Vicente J. Botet Escriba <
>>> vicente.botet_at_[hidden]> wrote:
>>> Le 09/02/2016 21:19, Kris a écrit :
>>>> On Tue, Feb 9, 2016 at 5:13 PM, Vicente Botet [via Boost] <
>>>>> ml-node+s2283326n4683364h3_at_[hidden]> wrote:
>>>>> Le 08/02/2016 20:32, Kris a écrit :
>>>>>> On Sat, Feb 6, 2016 at 10:34 PM, Vicente Botet [via Boost] <
>>>>>>> [hidden email] <http://
>>>>>>> /user/SendEmail.jtp?type=node&node=4683364&i=0>>
>>>>>>> wrote:
>>>>>> I don't think you should correlate whether MSM manage exceptions and
>>>>>> whether the configure function is noexcept.
>>>>>> Why not? I find it better then being forced to setup some dummy type in
>>>>> the
>>>>> state machine to enable exception handling.
>>>>> Please notice that exceptions handling is enabled by default (unless you
>>>>> compile with -fno-exceptions). The only reason why
>>>>> noexcept with configure when you create a transition table counts its
>>>>> because it will give you more performance.
>>>>> Why do you want to loss this performance when you want exceptions
>>>> enabled?
>>>> Couldn't the configure function be always noexcept?
>>>>> It's the opposite, I don't want to lose performance at any time.
>>> Exceptions
>>> handling cause a bit of overhead as you have to be in try { ... } catch
>>> statement.
>>> Well, C++ defines noexcept and that's a default, how would you like to
>>> mark
>>> that transition table can throw otherwise?. For example, noexcept(false)
>>> seems a bit silly to use.
>>> We don't have 'except' and therefore default behavior supports exceptions
>>> unless you disable them via compiler flag.
>>> I understand that the try-catch would take time, and must be
>> configurable. However I don't think that the noexcept qualification in the
>> configure function is correct, as the configure function will throw or not
>> independently on whether you have this try-catch, as it is related to the
>> transition firing, not the transition table construction.
> Yea, I do get your point but IMHO when you look at transition table
> (make_transion_table) and you see that configure function is noexcept it's
> quite easy to get what is going on, but again, it's just my opinion.
> I tried different approach before, when I was checking all guards/actions
> whether they are noexcept or not. The problem with this solution was that
> lambdas expression are usually written without the noexcept
> and, since the state machine was behaving the same, it was hard to notice
> that performance went done. All in all, I just like the idea of using
> facilities provided by the standard here. I know it's not exactly what
> one may expect as configure will never throw or be/should called by the
> user.
>> When you say " When guard/action throws an exception State Machine
>>>>>> will stay in a current state.", do you mean that if there is an
>>>>>> exception in the action part, the state will be the nesting state of
>>>>>> the
>>>>>> transition, as the exit of the source state will already be executed?
>>>>>> If
>>>>>> yes, this is not a leaf state, this is why I added a pseudo-state, to
>>>>>> ensure a leaf state.
>>>>>> It means that if exception won't be handled and that source state will
>>>>> remains the current state.
>>>>> Exit of the source state won't happen in such case too. Change the state
>>>>> happens
>>>>> after guards/actions were executed properly, otherwise source state is
>>>>> still a current state.
>>>>> src_state + event [ guard ] / action = dst_state
>>>>> ^
>>>>> |
>>>>> 1. src_state +
>>>>> on_exit
>>>>> 2. dst_state +
>>>>> on_entry
>>>>> I believed that the order IN UML was
>>>> 1 guard
>>>> 2 src_state exit
>>>> 3 action
>>>> 4 dst_state entry
>>>> 2,3,4 are executed only if the ward is true.
>>> I think UML doesn't specify the order when any of these should happen. At
>>> least I'm not aware of it, but I might be wrong?
>>> Anyway, defining it the following way
>>> 1 guard
>>> 2 action
>>> 3 src_state exit
>>> 4 change state
>>> 5 dst_state entry
>>> may things much easier to handle from programming perspective.
>> It seems others disagree with your point of view as they have chosen exit
>> before action :(
>> I don't have a link to the UML recommendation, but the wiki agrees with my
>> order.
> Yea, it seems like. It's easier to handle exceptions this way, however,
> being compliant with the UML is important.
> I may change the order then as it will save me time in the future
> explaining why it was done the other way ;)
> Thanks for pointing that out.
I will check it before. See below.
>> One doesn't
>>> have to deal with undefined states .
>> Well, as I said before, you must consider that there is a TOP state
>> associated to a SM. When you have a transition from S1 to S2, the action is
>> executed in the context of the TOP state.
>> I'm not saying that exit/action is better than action/exit, but if UML
>> defines the order exit/action I will see why before changing the semantics.
>> Just for the record, Boost.MSM has a policy to set when change state should
>>> happen.
>> I wonder what was the rationale for this possibility. What
>> Boost.Statechart does?
> No idea what Statechart does. MSM rationale is here ->
It seems that we need to inspect the UML2.1 documentation to check what
is the specified behavior. If it is undefined, the argument in MSM would
be valid.
> BTW. I have a question related to local transitions. Concept seems to be
> nice but I don't undesrtand why exit/entry is NOT triggered only 'if the
> main target state is a substate of the main source'.
> Why this concept can't be more general? Wouldn't that be nice?
> s1 + e1 = s2 // exit from s1 / entry to s2
> s1 ^ e1 = s2 // no exit from s1 / no entry to s2
A local transition will ensure that there is no exit on s1, but there
should be an entry in s2 if s2 is not s1.
You will need to have a nested examples to see the difference between an
external and a local transition.


Boost list run by bdawes at, gregod at, cpdaniel at, john at