[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?

280 views
Skip to first unread message

Krzysztof Jusiak

unread,
Jan 28, 2016, 11:20:20 AM1/28/16
to bo...@lists.boost.org, Christophe Henry
Dear Boosters,

I have recently released 1.0.0 version of experimental C++14 Boost.MSM-lite.
Your scalable C++14 header only eUML-like meta state machine library with
no dependencies, which outperform Boost.MSM - eUML in:
- faster compilation times - up to 60x times faster!
- smaller executable size - up to 15x smaller
- slightly better performance
- smaller memory usage
- short error messages

Check it out yourself online!
http://boost-experimental.github.io/msm-lite/examples/index.html#hello-world

Performance Results:
http://boost-experimental.github.io/msm-lite/overview/index.html#performance

Source code:
https://github.com/boost-experimental/msm-lite

Documentation:
http://boost-experimental.github.io/msm-lite

Any feedback is more than welcome!

Cheers, Kris

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Klaim - Joël Lamotte

unread,
Jan 28, 2016, 12:44:33 PM1/28/16
to Boost Developers List
On 28 January 2016 at 17:19, Krzysztof Jusiak <krzy...@jusiak.net> wrote:

> Dear Boosters,
>
> I have recently released 1.0.0 version of experimental C++14
> Boost.MSM-lite.
> Your scalable C++14 header only eUML-like meta state machine library with
> no dependencies, which outperform Boost.MSM - eUML in:
> - faster compilation times - up to 60x times faster!
> - smaller executable size - up to 15x smaller
>

I would be interest just because of these 2 points.
I see a lot of opportunities to use such library but most of the time I
can't afford
to use Boost.MSM because of the implied compile-time cost.

Krzysztof Jusiak

unread,
Jan 29, 2016, 5:57:39 AM1/29/16
to bo...@lists.boost.org
> I would be interest just because of these 2 points.
> I see a lot of opportunities to use such library but most of the time I
> can't afford
> to use Boost.MSM because of the implied compile-time cost.

Thanks for your feedback and yea, Boost.MSM is great; eUML is even better,
but it was written some time ago, before C++11.
It still uses Boost.MPL and Boost.Fusion which are pretty slow to compile
in comparison to
what can be achieved nowadays. On top of that, right now we have a lambda
expressions which were
emulated in eUML using Boost.Phoenix. All in all, C++11/14 give as a lot of
opportunities
to improve the situation and Boost.MSM-lite is just a small example how
much more user-friendly C++ might be
as well as how much faster the code might be compiled without loosing any
performance.

On Thu, Jan 28, 2016 at 5:44 PM, Klaim - Joël Lamotte <mjk...@gmail.com>
wrote:

Kris

unread,
Jan 29, 2016, 7:35:44 AM1/29/16
to bo...@lists.boost.org
Hi Paul,

Please find my answers below.

> The library looks very nice. A couple of things

Cheers

> First, it's not just C++14 only as it relies on compiler intristics which
> just happen to work on the three major compilers you support. It would be
> nice if
> you just relied on the standard library for these things.

Well, the library is pure C++14, however, as you mentioned, it uses an
compiler extension to create a compile time string. Having said that, it's
totally optional and it doesn't have to be used at all. What I mean by that
is that you can write:

using namespace msm;
auto state = "idle"_s;
//or
auto state = msm::state<class idle>{};
//or
msm::state<class idle> idle;

All of them will give the same result, however the first option
(non-standard one) just happen to be more convenient.

> Most likely, users are going to use the standard `type_traits` header
> anyway so this will
> cause a lot of duplication. Futhermore, the implementation of
> `make_index_sequence`
> can be much slower performance than the standard library since it doesn't
> take advantage of the compiler intristics that are available

It's true, however, available standard libraries are not always working the
same way. Especially MSVC standard library was giving me a lot of hard
times. For example. is_constructible was working differently,
make_index_sequence was recursive etc. and therefore I put the
implementation in the header as it was easier to maintain it. Anyway, most
of the times it uses compiler support either way like __is_base_of, etc., so
it's not a big deal. All in all its just 90 lines of code. I'm not saying I
won't use type_traits for it, but I don't see much gain from doing it right
now as I would have to put a lot of ifdefs there either way :/ Yea, I know
about make_index_sequence improvements in clang/gcc, but it's still not
available in the newest release of those compilers as far as I remember. I
would be really happy to change the implementation into
__make_index_sequence, for instance. The other point is the fact that not
being depended on STL allows embedded/console games/etc. developers to use
the library as they, in a lot of cases, don't have access to STL. To sum up,
I agree with your points and maybe the library will use type_traits header
at some point, however I don't see a lot of benefits of changing it right
now.

> Secondly, the documentation for the concepts seems confusing. In the
> documenatation it show the concept as this:
>
> template <class TResult, class T>
> concept bool callable() {
> return requires(T object) {
> { object(...) } -> TResult;
> }
> }
>
> I assume its written like this for notational purposes. However, the
> example
> shows it being used like this:
>
> auto guard = [] { return true; };
> auto action = [] { };
>
> static_assert(callable<bool, decltype(guard)>);
> static_assert(callable<void, decltype(action)>);
>
> Which is incorrect as in the code its an alias to an `integral_constant`,
> however, the `integral_constant` doesn't look like its fully implemented,
> so
> this fails as well:
>
> auto guard = [] { return true; };
> auto action = [] { };
>
> static_assert(callable<bool, decltype(guard)>());
> static_assert(callable<void, decltype(action)>());
>
>Of course, using `std::integral_constant` would make the above work.

Firstly, I'm not really using concepts-lite in the library, just a some
silly emulation, so yea, its just for notation purposes. Secondly, fair
point, documentation is wrong there, as above example will not compile.
Thanks for pointing that out. Anyway, library is no about concepts, they are
not exposed to be used
outside of the library. They help getting nicer error messages and they are
meant to stay this way.
But I get your point and I will change the documentation.

> Thirdly, Boost.Hana started out in a similiar fashion, being single header
> and not relying on the standard library. Of course, as it grew, it needed
> to use
> multiple headers and the standard library headers as well.

Yea, I remeber, however this library is meant to stay 'lite'. If it comes to
multiple headers.
I find it very useful to have just one header in the end. I have been using
this approach
in my experimental boost.di library too, however, there I generate the
header from
all hpp files. You can check it here:
https://github.com/boost-experimental/di

> Finally, I like the documentation setup. I use mkdocs as well for my
> documenation, and I created a boost theme to try and match the boost
> documentation. You can see it here: https://github.com/pfultz2/boost-theme
> Of course, its still a WIP. I, also, like the code snippets with option to
> compile and run the code online in the documentation. I think I am going
> to
> try to setup something similiar for my library as well.

Cheers, and thanks for the link, looks promising. I will defo take a look.
Yea, these days we can liven up documentation quite a lot with js.

Feel free to use solution provided, we can also merge your boost-theme with
my facilities to provide modern way of boost doc with mkdocs?

Thank you very much for your feedback!

Cheers, Kris



--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683064.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

christoph...@gmail.com

unread,
Jan 31, 2016, 4:41:31 PM1/31/16
to bo...@lists.boost.org
Hi Kris,

>I have recently released 1.0.0 version of experimental C++14
>Boost.MSM-lite.
>Your scalable C++14 header only eUML-like meta state machine library with
>no dependencies, which outperform Boost.MSM - eUML in:
>- faster compilation times - up to 60x times faster!
>- smaller executable size - up to 15x smaller
>- slightly better performance
>- smaller memory usage
>- short error messages

I find it quite nice. The idea is very interesting. Minor nitpicks, I find
weird mixing strings and <> syntax and the trick about inital states, but
it's really a matter of taste. It would also be good to avoid having to
declare events separately.
It would be interesting to see how it fares against the eUML successor,
eUML2 written using metaparse.

I do plan to rewrite parts of MSM and have a second look at eUML later this
year, so if you don't mind, I might use some of your ideas.

I'm wondering where you want to go from there. Rewriting all of MSM is quite
some work. But keeping the library lite is not really an option if you want
more than a toy library because most potential users will want more
features.

Actually, the whole idea of dividing MSM in back and front ends was exactly
to allow front-ends like yours as extensions. Would you be interested in
doing this instead? If changes in back-end are necessary, why not? It has to
be done anyway, as most of the library was written 7-8 years ago.
It might mean that there will be a pre and post C++14 versions, but I don't
think it matters.

Cheers,
Christophe

Kris

unread,
Feb 1, 2016, 6:21:53 AM2/1/16
to bo...@lists.boost.org
Hi Christophe,

Thank you very much for your feedback and time. I appreciate it a lot.

Yea, I like having everything visible on the transition table and therefore
I put initial states as well entry/exit actions there.
I know you have a different view on that, however, I find it easier to
follow this way.

Declare events on the fly its easy to do, however, I don't think it will
bring much value as events can be accessed outside
the transition table as well as they, most likely, will hold some data.
Therefore, I'm not sure about it. Might be useful to have
both options tho.

I would love to compare MSM-lite/MSM-eUML to eUML2, however I haven't seen
it yet besides some code in the emails.
Can you share a link to the eUML2 version, please? I will defo add
benchmarks for it.

I don't see any problem with that as MSM-lite is open source. I also offer
my help in designing and/or coding.

Well, I would like to keep the core of the library as small as possible as
in my experience a lot of users are actually not using
as many features. Having said that, I have no problems adding new features
via policies/extensions. Moreover, MSM-lite
is already used in some of the top growing mobile games, but yea, I do
agree that some users would like to see more features.
Anyway, are there any specific features you are talking about which are so
essential. I know that defer/history might be useful,
but I don't see much more features in MSM, besides explicit/fork states?

I totally admire MSM design. I really liked the separation between back and
front end. I have even implemented some extensions
myself:
* dependency injection support (https://github.com/krzysztof-jusiak/msm)
* testing support (https://github.com/krzysztof-jusiak/msm/tree/master)

And I also followed this approach in MSM-lite; it's not stated explicitly
but it might be found there.

Although it would be interesting to incorporate with MSM I'm afraid it's
not possible with the current MSM as MSM-lite has a different approach.
Especially back-end is achieved in a different way which is not compatible
with MSM. While MSM-lite front-end
still produces transitions-like types it holds objects and relay on
dependencies to be injected. All in all, MSM-lite it's quite different
than the current version of MSM. It maybe would be possible with a new
version of MSM, however there is no such a thing yet, is it?

Thank you again for your feedback!

Cheers,
Kris
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683114.html
> To unsubscribe from [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?, click here
> <http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=4683016&code=a3J6eXN6dG9mQGp1c2lhay5uZXR8NDY4MzAxNnwtMTY0MTkzNTIwMA==>
> .
> NAML
> <http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>




--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683123.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 2, 2016, 1:20:33 PM2/2/16
to bo...@lists.boost.org
Le 01/02/2016 11:57, Kris a écrit :
> Hi Christophe,
>
> Thank you very much for your feedback and time. I appreciate it a lot.
>
> Yea, I like having everything visible on the transition table and therefore
> I put initial states as well entry/exit actions there.
> I know you have a different view on that, however, I find it easier to
> follow this way.
>
> Declare events on the fly its easy to do, however, I don't think it will
> bring much value as events can be accessed outside
> the transition table as well as they, most likely, will hold some data.
> Therefore, I'm not sure about it. Might be useful to have
> both options tho.
>
> I would love to compare MSM-lite/MSM-eUML to eUML2, however I haven't seen
> it yet besides some code in the emails.
> Can you share a link to the eUML2 version, please? I will defo add
> benchmarks for it.
>
> I don't see any problem with that as MSM-lite is open source. I also offer
> my help in designing and/or coding.
Hi, IIUC you are proposing a 3rd MSM library in Boost, and you don't
pretend to make it a sub-library of Boost.MSM. If I'm right, I suggest
you to rename the namespace to msm_lite or whatever you find more
appropriated.

BTW, with the figures you gave I believe that there would be an interest
in your library.
>
> Well, I would like to keep the core of the library as small as possible as
> in my experience a lot of users are actually not using
> as many features. Having said that, I have no problems adding new features
> via policies/extensions. Moreover, MSM-lite
> is already used in some of the top growing mobile games, but yea, I do
> agree that some users would like to see more features.
> Anyway, are there any specific features you are talking about which are so
> essential. I know that defer/history might be useful,
> but I don't see much more features in MSM, besides explicit/fork states?
Well these are already quite a few features. I have not see local
transitions (different from internal transitions).

Please could you point me if you support choice points?
While choice points are unavoidable in graphical UML, I find it not very
useful while writing MSM in C++ as I prefer to do it using if or switch.
However having a transition table that can have only one next-state by
transition disable this possibility. I use to have a transition table
with a transition that has an action_nextstate that do the action and
returns the nextstate of the transition.

|"s2"_s + event<e2> [ guard ] / action_nextstate This avoids the storage
of local variable on the MSM data context. |


Have you considered this possibility?

Best,
Vicente

Vicente J. Botet Escriba

unread,
Feb 2, 2016, 1:41:42 PM2/2/16
to bo...@lists.boost.org
Oh, I see that you have anonymous transitions.



I see that MSM eUML defines the transitions like

target == source + event [guard] / action

but MSM-lite reverse the source and target

src_state == dst_state + event[ guard ] / action This is confusing.

Why have you chosen this syntax? Vicente

Klaim - Joël Lamotte

unread,
Feb 2, 2016, 2:09:41 PM2/2/16
to Boost Developers List
On 2 February 2016 at 19:41, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

>
> I see that MSM eUML defines the transitions like
>
> target == source + event [guard] / action
>
> but MSM-lite reverse the source and target
>
> src_state == dst_state + event[ guard ] / action This is confusing.
>
> Why have you chosen this syntax? Vicente
>
>

Same question here. I misread the examples at first because the meaning is
reversed.
It feels unnatural that the state you are going to is part of the
expression stating the conditions to get there.

The MSM syntax is clearer to me at least.

Krzysztof Jusiak

unread,
Feb 2, 2016, 4:13:00 PM2/2/16
to bo...@lists.boost.org
On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

> Le 01/02/2016 11:57, Kris a écrit :
>
>> Hi Christophe,
>>
>> Thank you very much for your feedback and time. I appreciate it a lot.
>>
>> Yea, I like having everything visible on the transition table and
>> therefore
>> I put initial states as well entry/exit actions there.
>> I know you have a different view on that, however, I find it easier to
>> follow this way.
>>
>> Declare events on the fly its easy to do, however, I don't think it will
>> bring much value as events can be accessed outside
>> the transition table as well as they, most likely, will hold some data.
>> Therefore, I'm not sure about it. Might be useful to have
>> both options tho.
>>
>> I would love to compare MSM-lite/MSM-eUML to eUML2, however I haven't seen
>> it yet besides some code in the emails.
>> Can you share a link to the eUML2 version, please? I will defo add
>> benchmarks for it.
>>
>> I don't see any problem with that as MSM-lite is open source. I also offer
>> my help in designing and/or coding.
>>
> Hi, IIUC you are proposing a 3rd MSM library in Boost, and you don't
> pretend to make it a sub-library of Boost.MSM. If I'm right, I suggest you
> to rename the namespace to msm_lite or whatever you find more appropriated.
>

Fair point, thanks for pointing it out. It's a valid concern. I have
nothing against changing the namespace/name as 'msm-lite' is just a working
title either way. Not sure what the best name should be tho?


> BTW, with the figures you gave I believe that there would be an interest
> in your library.
>
>>
>> Well, I would like to keep the core of the library as small as possible as
>> in my experience a lot of users are actually not using
>> as many features. Having said that, I have no problems adding new features
>> via policies/extensions. Moreover, MSM-lite
>> is already used in some of the top growing mobile games, but yea, I do
>> agree that some users would like to see more features.
>> Anyway, are there any specific features you are talking about which are so
>> essential. I know that defer/history might be useful,
>> but I don't see much more features in MSM, besides explicit/fork states?
>>
> Well these are already quite a few features. I have not see local
> transitions (different from internal transitions).


Yea interna(local) transitions are supported. Example here ->
http://boost-experimental.github.io/msm-lite/examples/index.html#transitions


>
>
Please could you point me if you support choice points?

While choice points are unavoidable in graphical UML, I find it not very
> useful while writing MSM in C++ as I prefer to do it using if or switch.
> However having a transition table that can have only one next-state by
> transition disable this possibility. I use to have a transition table with
> a transition that has an action_nextstate that do the action and returns
> the nextstate of the transition.
>
> |"s2"_s + event<e2> [ guard ] / action_nextstate This avoids the storage
> of local variable on the MSM data context. |
>
>
> Have you considered this possibility?
>

Interesting idea, can you elaborate please as I'm not sure whether I follow
the idea with the action_nextstate?
If it comes to the choice points, I guess the easier way is just to have
multiple transitions from the same state?

make_transition_table(
s1 -> s2 + e2 [some_guard1 && some_guard2] / action1
, s1 -> s3 + e2 [other_guard] / action2
, s1 + e2 / action3
);

would be the same as

if (e2) {
if (some_guard1 && some_guard2) {
action1;
change_state_to(s2);
} else if(other_guard) {
action2;
change_state_to(s3);
} else {
action3;
}
}


>
> Best,
> Vicente
>

Thank you for you feedback.

Cheers, Kris

Krzysztof Jusiak

unread,
Feb 2, 2016, 4:18:51 PM2/2/16
to bo...@lists.boost.org
On Tue, Feb 2, 2016 at 6:41 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:
>
> Oh, I see that you have anonymous transitions.
>
>
>
> I see that MSM eUML defines the transitions like
>
> target == source + event [guard] / action
>
> but MSM-lite reverse the source and target
>
> src_state == dst_state + event[ guard ] / action This is confusing.
>
> Why have you chosen this syntax? Vicente


Well, I read it from left to right and therefore I found it more natural
for me to do it this way. However, msm-lite supports both syntaxes.
You change it to dst_state == src_state by setting
up BOOST_MSM_DSL_DST_STATE_FIRST. Currently the default is src == dst but
it might be changed
to the, less confusing, one if that what devs are more comfortable with.

You can find an example here ->
http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulation

Cheers for the question, Kris

Krzysztof Jusiak

unread,
Feb 2, 2016, 4:29:57 PM2/2/16
to bo...@lists.boost.org
On Tue, Feb 2, 2016 at 7:09 PM, Klaim - Joël Lamotte <mjk...@gmail.com>
wrote:

> On 2 February 2016 at 19:41, Vicente J. Botet Escriba <


> vicent...@wanadoo.fr> wrote:
>
> >
> > I see that MSM eUML defines the transitions like
> >
> > target == source + event [guard] / action
> >
> > but MSM-lite reverse the source and target
> >
> > src_state == dst_state + event[ guard ] / action This is confusing.
> >
> > Why have you chosen this syntax? Vicente
> >
> >
>
> Same question here. I misread the examples at first because the meaning is
> reversed.
> It feels unnatural that the state you are going to is part of the
> expression stating the conditions to get there.
>
> The MSM syntax is clearer to me at least.


I see your point. It seems like I will have to change the default behaviour
then as it's clearer for most devs. Guess, I'm the ackward one here.
Please, check the euML emulation example ->
http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulation
as DSL
behaviour might be changed if it comes to states order by defining
BOOST_MSM_DSL_DST_STATE_FIRST.

If it comes to the transition table DSL. I was concidering a lot of
options. For example MSM3(eUML2) is using src + event [guard] / action ->
dst
which looks great, however, having a dst state at the end is not really
practical, especially after a lot of noice introduced by guard and actions
(for example in place lambda expressions).

Right now, I'm thinking of introducing DSL which would look like that.

make_transition_table(
"idle* -> state1"_t + event [ guard ] / action
, "state1 -> X"_t [ guard ] / action
);

Nevertheless, I'm not sure whether such approach would be seen positively
because following MSM approach it should be more like that.

make_transition_table(
"state1 <- idle*"_t + event [ guard ] / action
, "X <- state1"_t [ guard ] / action
);

which looks confusing for me. Any thought on this?

Thanks for your feedback,
Cheers, Kris

Klaim - Joël Lamotte

unread,
Feb 2, 2016, 5:18:57 PM2/2/16
to Boost Developers List

I was going to suggest <= and => but I don't know the potential problems.

Kris

unread,
Feb 2, 2016, 5:26:36 PM2/2/16
to bo...@lists.boost.org
On Tue, Feb 2, 2016 at 9:55 PM, Klaim - Joël Lamotte [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> On 2 February 2016 at 22:29, Krzysztof Jusiak <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4683151&i=0>> wrote:
>
> > On Tue, Feb 2, 2016 at 7:09 PM, Klaim - Joël Lamotte <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4683151&i=1>>


> > wrote:
> >
> > > On 2 February 2016 at 19:41, Vicente J. Botet Escriba <

> > > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683151&i=2>>

It's a compile time string parsing so there are no issues with characters
here, just the design.
So your suggestion would be:

// *=initial

"state1 <= idle*"

or

"idle* => state1"

is that correct?

'->' was chosen, simply because it might be found in the UML2
specification, but there are no limitations here. Whatever works the best.

Thanks for the suggestion, Kris


>
> > Thanks for your feedback,
> > Cheers, Kris
> >
> >
> > _______________________________________________
> > > Unsubscribe & other changes:
> > > http://lists.boost.org/mailman/listinfo.cgi/boost
> > >
> >
> > _______________________________________________
> > Unsubscribe & other changes:
> > http://lists.boost.org/mailman/listinfo.cgi/boost
> >
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683151.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683152.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Rob Stewart

unread,
Feb 3, 2016, 4:36:36 AM2/3/16
to bo...@lists.boost.org
On February 2, 2016 4:29:35 PM EST, Krzysztof Jusiak <krzy...@jusiak.net> wrote:
>
> If it comes to the transition table DSL. I was concidering a lot of
> options. For example MSM3(eUML2) is using src + event [guard] / action
> -> dst
> which looks great, however, having a dst state at the end is not
> really
> practical, especially after a lot of noice introduced by guard and
> actions
> (for example in place lambda expressions).

Agreed

> Right now, I'm thinking of introducing DSL which would look like that.
>
> make_transition_table(
> "idle* -> state1"_t + event [ guard ] / action
> , "state1 -> X"_t [ guard ] / action
> );
>
> Nevertheless, I'm not sure whether such approach would be seen
> positively
> because following MSM approach it should be more like that.
>
> make_transition_table(
> "state1 <- idle*"_t + event [ guard ] / action
> , "X <- state1"_t [ guard ] / action
> );

We're accustomed to seeing the target on the left of an assignment, so what about "state1 = idle*"?

I get your interest in seeing the current state on the left, because the transition is from the current state to the new one. If there can be multiple transitions from one state, the only readable form puts the current state first, IMO. Using "if_" or "when" to separate the transition from the condition might help:

(from -> to).when(event[guard]/condition)

You could omit "when" with the parens:

from -> to (event[guard]/condition)

___
Rob

(Sent from my portable computation engine)

Kris

unread,
Feb 3, 2016, 9:11:11 AM2/3/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 9:12 AM, Rob Stewart [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> On February 2, 2016 4:29:35 PM EST, Krzysztof Jusiak <[hidden email]
Thanks for your valuable input. Yea, it's all about the parens in the end.
Right now I do understand that my assumptions were wrong as I was putting
the parens (in my mind) the following way.
(s1 == s2) + event [ guard ] / action (although they weren't really there).

Anyway, thanks to the input provided I realized it wasn't the best idea and
therefore I have changed the DSL to.

// Prefix Notation
"state"_s <= *"idle"_s + event [ guard ] / action

// Postfix Notation
*"idle"_s + event [ guard ] / action = "state"_s

// '=>' would be better, however C++ only allows for '>=' which is not
ideal here

Moreover, I have added a few UML-like notations. For initial state(*),
terminate state(X), history state(H).

X <= "idle"_s(H) + event [ guard ] / action

or

"idle"_s(H) + event [ guard ] / action = X

Please take a look at the new versions of examples:

http://boost-experimental.github.io/msm-lite/examples/index.html#hello-world

http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulation

http://boost-experimental.github.io/msm-lite/examples/index.html#sdl2-integration

and please let me know what do you think.

Cheers, Kris


> ___
> Rob
>
> (Sent from my portable computation engine)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683164.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683167.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Kris

unread,
Feb 3, 2016, 10:50:35 AM2/3/16
to bo...@lists.boost.org
On Mon, Feb 1, 2016 at 11:21 AM, Krzysztof Jusiak <krzy...@jusiak.net>
wrote:

> Hi Christophe,
>
> Thank you very much for your feedback and time. I appreciate it a lot.
>
> Yea, I like having everything visible on the transition table and
> therefore I put initial states as well entry/exit actions there.
> I know you have a different view on that, however, I find it easier to
> follow this way.
>
> Declare events on the fly its easy to do, however, I don't think it will
> bring much value as events can be accessed outside
> the transition table as well as they, most likely, will hold some data.
> Therefore, I'm not sure about it. Might be useful to have
> both options tho.
>
> I would love to compare MSM-lite/MSM-eUML to eUML2, however I haven't seen
> it yet besides some code in the emails.
> Can you share a link to the eUML2 version, please? I will defo add
> benchmarks for it.
>

I added a simple benchmark using Boost.MSM3-eUML2 to the performance tests.
Results can be found here ->
http://boost-experimental.github.io/msm-lite/overview/index.html#performance

It seems that Boost.MSM3-eUML2 (not sure what is the proper name?) compiles
2.5 times slower than the eUML, but maybe there are some flags/options to
speed it up?

Moreover, I'm not sure how to disable the slowing down options such as
deffered events etc.?
I would assume it should be as fast as eUML as it using the same back-end?

I have also noticed that the parser is not really strict as you can write
not valid code which will compiles. For example.
EUML2_ROW("Stopped + stop / stopped_again - Stopped"); // - instead
of ->


>
I don't see any problem with that as MSM-lite is open source. I also offer
> my help in designing and/or coding.
>
> Well, I would like to keep the core of the library as small as possible as
> in my experience a lot of users are actually not using
> as many features. Having said that, I have no problems adding new features
> via policies/extensions. Moreover, MSM-lite
> is already used in some of the top growing mobile games, but yea, I do
> agree that some users would like to see more features.
> Anyway, are there any specific features you are talking about which are so
> essential. I know that defer/history might be useful,
> but I don't see much more features in MSM, besides explicit/fork states?
>
> I totally admire MSM design. I really liked the separation between back
> and front end. I have even implemented some extensions
> myself:
> * dependency injection support (https://github.com/krzysztof-jusiak/msm)
> * testing support (https://github.com/krzysztof-jusiak/msm/tree/master)
>
> And I also followed this approach in MSM-lite; it's not stated explicitly
> but it might be found there.
>
> Although it would be interesting to incorporate with MSM I'm afraid it's
> not possible with the current MSM as MSM-lite has a different approach.
> Especially back-end is achieved in a different way which is not compatible
> with MSM. While MSM-lite front-end
> still produces transitions-like types it holds objects and relay on
> dependencies to be injected. All in all, MSM-lite it's quite different
> than the current version of MSM. It maybe would be possible with a new
> version of MSM, however there is no such a thing yet, is it?
>
> Thank you again for your feedback!
>
> Cheers,
> Kris
>
> On Sun, Jan 31, 2016 at 9:18 PM, Christophe Henry-2 [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>
>> ------------------------------
>> If you reply to this email, your message will be added to the discussion
>> below:
>>
>> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683114.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683170.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 3, 2016, 2:12:06 PM2/3/16
to bo...@lists.boost.org
Le 02/02/2016 22:12, Krzysztof Jusiak a écrit :
> On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr> wrote:
>
>> Le 01/02/2016 11:57, Kris a écrit :
>>
>>>
>> Hi, IIUC you are proposing a 3rd MSM library in Boost, and you don't
>> pretend to make it a sub-library of Boost.MSM. If I'm right, I suggest you
>> to rename the namespace to msm_lite or whatever you find more appropriated.
>>
> Fair point, thanks for pointing it out. It's a valid concern. I have
> nothing against changing the namespace/name as 'msm-lite' is just a working
> title either way. Not sure what the best name should be tho?
Well, you would need to choose a name ;-)

>
>
>>
>> Well these are already quite a few features. I have not see local
>> transitions (different from internal transitions).
>
> Yea interna(local) transitions are supported. Example here ->
> http://boost-experimental.github.io/msm-lite/examples/index.html#transitions
>
Internal and local transitions are not the same. How do you make
syntactically the difference. I've not see and reference to local
transitions.
This is almost the idea. But the use case is the followings, sorry I
will use the src + evt / act = dst notation

make_transition_table(
s0 + e / action0 -> cp
cp [some_guard1] / action1 -> s1
cp [else] / action2 -> s2
);


With action-next-state transition could be

s0 + e / action_nextstate

where action_nextstate is

auto action_nextstate = [](auto const& evt) {
action0;
if (some_guard1) {
action1;
next_state(s1); // You could also return a state if there is a
type that can store any state of the state machine.
} else {
action2;
next_state(s2);
}
}

Note that these action-nextstate could define some local variables in
action0 that can be used in some_guard1 and in action1 and action2 .

The uml transition schema forces to store these local variable on the
state machine context (or a state context if supported), which is less
than optimal. This is needed because there is no way to share variables
between the action0, some_guard1 and in action1 and action2. In addition
action1 and action2 have no access to the event e, as only the action0
has it as parameter.

Do you think that this kind of transitions goes against the UML semantics?

Best,
Vicente

Kris

unread,
Feb 3, 2016, 4:12:27 PM2/3/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> Le 02/02/2016 22:12, Krzysztof Jusiak a écrit :
>
> > On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba <

> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683171&i=0>>


> wrote:
> >
> >> Le 01/02/2016 11:57, Kris a écrit :
> >>
> >>>
> >> Hi, IIUC you are proposing a 3rd MSM library in Boost, and you don't
> >> pretend to make it a sub-library of Boost.MSM. If I'm right, I suggest
> you
> >> to rename the namespace to msm_lite or whatever you find more
> appropriated.
> >>
> > Fair point, thanks for pointing it out. It's a valid concern. I have
> > nothing against changing the namespace/name as 'msm-lite' is just a
> working
> > title either way. Not sure what the best name should be tho?
> Well, you would need to choose a name ;-)
> >
> >
> >>
> >> Well these are already quite a few features. I have not see local
> >> transitions (different from internal transitions).
> >
> > Yea interna(local) transitions are supported. Example here ->
> >
> http://boost-experimental.github.io/msm-lite/examples/index.html#transitions
> >
> Internal and local transitions are not the same. How do you make
> syntactically the difference. I've not see and reference to local
> transitions.
>

> Actually, I'm not sure what the difference is, sorry. I checked the UML2
spec and there is no much
about local transitions there. Bascially that, 'internal is a special case
of a local Transition that is a self-transition'.
Can you explain how it supose to work, please and what syntax would be
preferable?

Actually msm-lite, since today, supports almost this syntax. There are
pre/post fix notations available.
src_state + event [guard] / action = dst_state
or
dst_state <= src_state + event [guard] / action

Hmm, interesting idea. However, it seems to be against the transition table
concept a bit
as guards are hidden in the actions instead. I do understand the concept
tho, it's more
like custom_reaction in the Boost.Statechart. I would still model it using
transition table
because it makes it more visible/clear to understand what is going on. With
action_nexstate approach
you have to check all actions to verify whether they are not changing the
state which might
be tricky to do. Unless, you have a solution for that?

BTW. msm-lite has a bit different approach than MSM to share the data
because guards/actions
may share data as objects are injected into them when they are required.
For example,

auto action = [] {}; // action, not data, no event
auto action_with_some_data = [] (int i, data& d) {}
auto action_with_some_data_and_event = [] (int i, const auto & event, data&
d) {} // order doesn't matter

auto guard_with_data = [] (data& d, const auto& event) { return true; }

make_transition_table(
*s1 + e1 [ guard_with_data ] / action = s2
, s2 + e2 / (action_with_some_data, action_with_some_data_and_event)
);

data d;
sm fsm{d, 42}; // order doesn't matter, this data will be injected into
guards/actions

It's a bit tedious to pass all required objects into state machine
constructor and therefore depenendy injection framework
may become handy here, for example experimental boost.di ->
https://github.com/boost-experimental/di

More examples:
http://boost-experimental.github.io/msm-lite/examples/index.html#actions-guards
http://boost-experimental.github.io/msm-lite/examples/index.html#dependency-injection

Thanks for your feedback, Kris


>
> Best,
> Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683171.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683175.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

christoph...@gmail.com

unread,
Feb 3, 2016, 4:15:09 PM2/3/16
to bo...@lists.boost.org
>I added a simple benchmark using Boost.MSM3-eUML2 to the performance tests.
>Results can be found here ->
>http://boost-experimental.github.io/msm-lite/overview/index.html#performance
>
>It seems that Boost.MSM3-eUML2 (not sure what is the proper name?) compiles
>2.5 times slower than the eUML, but maybe there are some flags/options to
>speed it up?
>
>Moreover, I'm not sure how to disable the slowing down options such as
>deffered events etc.?
>I would assume it should be as fast as eUML as it using the same back-end?

Compile-time is proportional to string length, reducing it would help.
So would reducing BOOST_MPL_LIMIT_STRING_SIZE.

As they are empty, you can also remove you action definitions.

christoph...@gmail.com

unread,
Feb 3, 2016, 4:18:22 PM2/3/16
to bo...@lists.boost.org
>Moreover, I'm not sure how to disable the slowing down options such as
deffered events etc.?

I would be surprised if deferred events costed much compile time.

Kris

unread,
Feb 3, 2016, 4:52:10 PM2/3/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 8:51 PM, Christophe Henry-2 [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> >I added a simple benchmark using Boost.MSM3-eUML2 to the performance
> tests.
> >Results can be found here ->
> >
> http://boost-experimental.github.io/msm-lite/overview/index.html#performance
> >
> >It seems that Boost.MSM3-eUML2 (not sure what is the proper name?)
> compiles
> >2.5 times slower than the eUML, but maybe there are some flags/options to
> >speed it up?
> >
> >Moreover, I'm not sure how to disable the slowing down options such as
> >deffered events etc.?
> >I would assume it should be as fast as eUML as it using the same
> back-end?
>
> Compile-time is proportional to string length, reducing it would help.
> So would reducing BOOST_MPL_LIMIT_STRING_SIZE.
>
> As they are empty, you can also remove you action definitions.
>
>
Cheers, I have been experimenting with BOOST_MPL_LIMIT_STRING_SIZE already.
However, it would be a bit bias to remove actions/guards in order to speed
it up as it would not reflect the real life example. I know they are not
doing much in the example, but
they still have to be called or removed by the compiler depending on the
approach.
For example msm-lite is affected by empty guards/actions if it comes to
memory size as it stores them in order to call lambda expressions.


>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683176.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683178.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Kris

unread,
Feb 3, 2016, 4:56:07 PM2/3/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 8:54 PM, Christophe Henry-2 [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> >Moreover, I'm not sure how to disable the slowing down options such as
> deffered events etc.?
>
> I would be surprised if deferred events costed much compile time.
>
> Yea, I agree that compilation time should not be affected. However a
runtime performance could have, right?
I was asking becuase it can be clearly seen that eUML2 is ~5 times slower
than eUML (17ms vs 100ms) and
therefore I assumed that not the same back-end is used, in a sens, that is
less optimized, because it has
some features enabled by default.

_______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683177.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683179.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 3, 2016, 5:23:35 PM2/3/16
to bo...@lists.boost.org
Le 03/02/2016 21:48, Kris a écrit :
> On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>
>> Le 02/02/2016 22:12, Krzysztof Jusiak a écrit :
>>
>>> On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba <
>>> [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683171&i=0>>
>>>> Well these are already quite a few features. I have not see local
>>>> transitions (different from internal transitions).
>>> Yea interna(local) transitions are supported. Example here ->
>>>
>> http://boost-experimental.github.io/msm-lite/examples/index.html#transitions
>> Internal and local transitions are not the same. How do you make
>> syntactically the difference. I've not see and reference to local
>> transitions.
>>
>> Actually, I'm not sure what the difference is, sorry. I checked the UML2
> spec and there is no much
> about local transitions there. Bascially that, 'internal is a special case
> of a local Transition that is a self-transition'.
> Can you explain how it supose to work, please and what syntax would be
> preferable?
>
A local transition
(https://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transitions)
form an outer state to itself exists from the most inner state but don't
exit from the outer state. If in addition the local transition goes to a
history state the inner state in re-entered.

An internal transition don't exits at all.

I have no preference for the notation, but why not replace the + sign
with a ^

src ^ event [guard] / action = src

src ^ event [guard] / action = src(H)

>>> Please could you point me if you support choice points?
>>>

> Actually msm-lite, since today, supports almost this syntax. There are
> pre/post fix notations available.
> src_state + event [guard] / action = dst_state
> or
> dst_state <= src_state + event [guard] / action

I know.

I'll take a look at. Yes, this can be seen as a drawback as less
visible, but performances are important in C++.


> I would still model it using
> transition table
> because it makes it more visible/clear to understand what is going on. With
> action_nexstate approach
> you have to check all actions to verify whether they are not changing the
> state which might
> be tricky to do. Unless, you have a solution for that?

One possibility is to return the next-state.

You could also restrict the possible next states in the table.

s0 + e / action_nextstate(s1, s2)

>
> BTW. msm-lite has a bit different approach than MSM to share the data
> because guards/actions
> may share data as objects are injected into them when they are required.
> For example,
>
> auto action = [] {}; // action, not data, no event
> auto action_with_some_data = [] (int i, data& d) {}
> auto action_with_some_data_and_event = [] (int i, const auto & event, data&
> d) {} // order doesn't matter
>
> auto guard_with_data = [] (data& d, const auto& event) { return true; }
>
> make_transition_table(
> *s1 + e1 [ guard_with_data ] / action = s2
> , s2 + e2 / (action_with_some_data, action_with_some_data_and_event)
> );
>
> data d;
> sm fsm{d, 42}; // order doesn't matter, this data will be injected into
> guards/actions

Hmm, this will not reduce the size of the shared data. What I want is to
be able to use local data shared between transition segments. This local
could be encoded in the transition table, but I'm not sure it is worth
the effort.


> It's a bit tedious to pass all required objects into state machine
> constructor and therefore depenendy injection framework
> may become handy here, for example experimental boost.di ->
> https://github.com/boost-experimental/di
>
> More examples:
> http://boost-experimental.github.io/msm-lite/examples/index.html#actions-guards
> http://boost-experimental.github.io/msm-lite/examples/index.html#dependency-injection
>
>

I don't understand how this helps in this context.

Vicente J. Botet Escriba

unread,
Feb 3, 2016, 5:40:43 PM2/3/16
to bo...@lists.boost.org
Le 03/02/2016 22:32, Kris a écrit :
> On Wed, Feb 3, 2016 at 8:54 PM, Christophe Henry-2 [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>
>>> Moreover, I'm not sure how to disable the slowing down options such as
>> deffered events etc.?
>>
>> I would be surprised if deferred events costed much compile time.
>>
>> Yea, I agree that compilation time should not be affected. However a
> runtime performance could have, right?
Event deferral must not cost anything at run-time if not used. Otherwise
it should be provided at a higher level.

The same applies to history state.

Of course, these features imply some extra space.

Vicente

Rob Stewart

unread,
Feb 4, 2016, 6:05:22 AM2/4/16
to bo...@lists.boost.org
On February 3, 2016 3:48:14 PM EST, Kris <krzy...@jusiak.net> wrote:

[snip]

> Actually msm-lite, since today, supports almost this syntax. There are
> pre/post fix notations available.
> src_state + event [guard] / action = dst_state
> or
> dst_state <= src_state + event [guard] / action

Why = for the one and <= for the other? Can't you use = for both?

[snip discussion of action-nextstate]

[snip quoting of irrelevant content]

___
Rob

(Sent from my portable computation engine)

Kris

unread,
Feb 4, 2016, 6:09:38 AM2/4/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 9:59 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> Le 03/02/2016 21:48, Kris a écrit :
>
> > On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] <

> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683180&i=0>>

I have seen it, thanks. Yea, local transitions are not supported currently
by msm-lite.
Are they supported by MSM? I haven't seen support for it there too. Anyway,
they are
not hard to implement. Do you have any important use case for them?


>
> An internal transition don't exits at all.
>
> I have no preference for the notation, but why not replace the + sign
> with a ^
>
> src ^ event [guard] / action = src
>
> src ^ event [guard] / action = src(H)
>
>

Well, I have just followed MSM approach and '+' was used there and I was
fine with it.
Is there any reason why '+' is wrong and it should be replaced with '^'
instead?

I implemented action_nextstate, so please take a look.
It might be checked online HERE ->
http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO

It's really easy to implement it, the basic idea below.

auto action_nextstate = [](auto... s) {
std::tuple<decltype(s)...> states{s...};
return [=](msm::sm<auto>& sm, auto const& evt, bool external_value) {
action0();
if (some_guard1(external_value)) {
action1();
sm.change_state(std::get<0>(states));
} else {
action2(evt);
sm.change_state(std::get<1>(states));
}
};
};

I had to add `change_state` to the msm-lite as it doesn't support changing
states unless in testing mode.

template <class... TStates>
void change_state(const detail::state<TStates> &...) noexcept {
decltype(current_state_) new_states = {aux::get_id<states_ids_t, 0,
TStates>()...};
*current_state_ = *new_states;
}

I hope that helps.I do understand your concept, however I'm not sure
whether such approach
is the best, but, at least, it's easy to implement. I guess if you can
prove that this is a common
case and that performance might be gained using it then it's worth to
consider such practice in general.

>
> > BTW. msm-lite has a bit different approach than MSM to share the data
> > because guards/actions
> > may share data as objects are injected into them when they are required.
> > For example,
> >
> > auto action = [] {}; // action, not data, no event
> > auto action_with_some_data = [] (int i, data& d) {}
> > auto action_with_some_data_and_event = [] (int i, const auto & event,
> data&
> > d) {} // order doesn't matter
> >
> > auto guard_with_data = [] (data& d, const auto& event) { return true; }
> >
> > make_transition_table(
> > *s1 + e1 [ guard_with_data ] / action = s2
> > , s2 + e2 / (action_with_some_data, action_with_some_data_and_event)
> > );
> >
> > data d;
> > sm fsm{d, 42}; // order doesn't matter, this data will be injected into
> > guards/actions
> Hmm, this will not reduce the size of the shared data. What I want is to
> be able to use local data shared between transition segments. This local
> could be encoded in the transition table, but I'm not sure it is worth
> the effort.


Me neither, so again, please take a look into the example and experiment
with it (http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO). It's
defo worth trying it out.


> > It's a bit tedious to pass all required objects into state machine
> > constructor and therefore depenendy injection framework
> > may become handy here, for example experimental boost.di ->
> > https://github.com/boost-experimental/di
> >
> > More examples:
> >
> http://boost-experimental.github.io/msm-lite/examples/index.html#actions-guards
> >
> http://boost-experimental.github.io/msm-lite/examples/index.html#dependency-injection
> >
> >
> I don't understand how this helps in this context.
>

Probably is not as your idea is based on local and not external data. I
misunderstood your concept at first.


>
> Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683180.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683203.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Kris

unread,
Feb 4, 2016, 6:20:39 AM2/4/16
to bo...@lists.boost.org
On Thu, Feb 4, 2016 at 10:41 AM, Rob Stewart [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> On February 3, 2016 3:48:14 PM EST, Kris <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4683202&i=0>> wrote:
>
> [snip]
>
> > Actually msm-lite, since today, supports almost this syntax. There are
> > pre/post fix notations available.
> > src_state + event [guard] / action = dst_state
> > or
> > dst_state <= src_state + event [guard] / action
>
> Why = for the one and <= for the other? Can't you use = for both?
>

Fair point, its not really consistent, is it?
The initial idea was to have <= in the prefix notation and => in the
postfix one. However the latter had to become >= which was quite awkward.
I guess it can be changed into.

dst = src + event [guard] / action
and
src + event[guard] / action = dst

I'm just not sure whether this approach is not confusing as we have the
same syntax for both notations, but sometimes src and sometimes dst is used
on the left side?
Do you think, if it possible, it would be better to use = for both
notations?


> [snip discussion of action-nextstate]
>
> [snip quoting of irrelevant content]
>
> ___
> Rob
>
> (Sent from my portable computation engine)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683202.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683204.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Kris

unread,
Feb 4, 2016, 6:26:02 AM2/4/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 10:17 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> Le 03/02/2016 22:32, Kris a écrit :
>
> > On Wed, Feb 3, 2016 at 8:54 PM, Christophe Henry-2 [via Boost] <

> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683181&i=0>>


> wrote:
> >
> >>> Moreover, I'm not sure how to disable the slowing down options such as
> >> deffered events etc.?
> >>
> >> I would be surprised if deferred events costed much compile time.
> >>
> >> Yea, I agree that compilation time should not be affected. However a
> > runtime performance could have, right?
> Event deferral must not cost anything at run-time if not used. Otherwise
> it should be provided at a higher level.
>
> The same applies to history state.
>
> Of course, these features imply some extra space.
>
>

Totally agree and this approach is taken by msm-lite as well as MSM.
However, you can see that eUML2 (successor of eUML) is slower than eUML in
the sample test
and therefore my confusion if it didn't have those features turned on by
default as the same
back-end is used for both.

http://boost-experimental.github.io/msm-lite/overview/index.html#performance

MSM requires to turn defferal events/queue etc. by adding a typedef
to the state machine. All in all, it is just an assumption as I don't know
the implementation details of eUML2, maybe it's just slower?


> Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683181.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683205.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Kris

unread,
Feb 5, 2016, 7:36:02 AM2/5/16
to bo...@lists.boost.org
On Wed, Feb 3, 2016 at 9:51 PM, Krzysztof Jusiak <krzy...@jusiak.net>
wrote:

> On Wed, Feb 3, 2016 at 8:51 PM, Christophe Henry-2 [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>
>> >I added a simple benchmark using Boost.MSM3-eUML2 to the performance
>> tests.
>> >Results can be found here ->
>> >
>> http://boost-experimental.github.io/msm-lite/overview/index.html#performance
>> >
>> >It seems that Boost.MSM3-eUML2 (not sure what is the proper name?)
>> compiles
>> >2.5 times slower than the eUML, but maybe there are some flags/options
>> to
>> >speed it up?
>> >
>> >Moreover, I'm not sure how to disable the slowing down options such as
>> >deffered events etc.?
>> >I would assume it should be as fast as eUML as it using the same
>> back-end?
>>
>> Compile-time is proportional to string length, reducing it would help.
>> So would reducing BOOST_MPL_LIMIT_STRING_SIZE.
>>
>> As they are empty, you can also remove you action definitions.
>>
>>
> Cheers, I have been experimenting with BOOST_MPL_LIMIT_STRING_SIZE already.
> However, it would be a bit bias to remove actions/guards in order to speed
> it up as it would not reflect the real life example. I know they are not
> doing much in the example, but
> they still have to be called or removed by the compiler depending on the
> approach.
> For example msm-lite is affected by empty guards/actions if it comes to
> memory size as it stores them in order to call lambda expressions.
>
>

I added composite and complex tests using eUML2 front end ->
http://boost-experimental.github.io/msm-lite/overview/index.html#performance
Actually, I haven't noticed a huge trade-offs whilst limiting
BOOST_MPL_LIMIT_STRING_SIZE length - max around 20%.
Anyway, interesting finding is the fact that eUML2, although compiling
around 2.5x time slower than eUML, compiles faster on the complex test
using Clang!
On GCC is still 2x slower then eUML but Clang has done some amazing job
here. Ah, I have also figured out why eUML2 was slower than eUML in my
previous
tests. I had to disable exceptions, message queue add add empty
no_transition handler.
Hope you find the results interesting too.


>> _______________________________________________
>> Unsubscribe & other changes:
>> http://lists.boost.org/mailman/listinfo.cgi/boost
>>
>>
>> ------------------------------
>> If you reply to this email, your message will be added to the discussion
>> below:
>>
>> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683176.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683249.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 5, 2016, 12:55:40 PM2/5/16
to bo...@lists.boost.org, Christophe Henry
Le 28/01/2016 17:19, Krzysztof Jusiak a écrit :
> Dear Boosters,
>
> I have recently released 1.0.0 version of experimental C++14 Boost.MSM-lite.
> Your scalable C++14 header only eUML-like meta state machine library with
> no dependencies, which outperform Boost.MSM - eUML in:
> - faster compilation times - up to 60x times faster!
> - smaller executable size - up to 15x smaller
> - slightly better performance
> - smaller memory usage
> - short error messages
>
>
Hi,

I have not found anything about how exceptions are managed nor about
inheritance of state machines. Is there something related to these two
subjects on your library?

Best,
Vicente

P.S. Sorry, I don't know how MSM or statecharts covers these subjects.

Vicente J. Botet Escriba

unread,
Feb 5, 2016, 1:37:16 PM2/5/16
to bo...@lists.boost.org
Le 04/02/2016 11:45, Kris a écrit :
> On Wed, Feb 3, 2016 at 9:59 PM, Vicente Botet [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>> A local transition
>> (
>> https://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transitions)
>>
>> form an outer state to itself exists from the most inner state but don't
>> exit from the outer state. If in addition the local transition goes to a
>> history state the inner state in re-entered.
>>
> I have seen it, thanks. Yea, local transitions are not supported currently
> by msm-lite.
> Are they supported by MSM? I haven't seen support for it there too. Anyway,
> they are
> not hard to implement. Do you have any important use case for them?
I don't know what important would mean here. I use them in my daily work
so that I ensure that I don't exit from a state (representing an
activity) until the activity is finished. I use to use them with the
history state, but there are other uses without.
The implementation is simple and they are part of UML2. I find this
enough motivating.

>
>
>> An internal transition don't exits at all.
>>
>> I have no preference for the notation, but why not replace the + sign
>> with a ^
>>
>> src ^ event [guard] / action = src
>>
>> src ^ event [guard] / action = src(H)
>>
>>
> Well, I have just followed MSM approach and '+' was used there and I was
> fine with it.
> Is there any reason why '+' is wrong and it should be replaced with '^'
> instead?
You misunderstood me. + will represent external transitions, while ^
could represent local transitions.

>> With
>>> action_nexstate approach
>>> you have to check all actions to verify whether they are not changing
>> the
>>> state which might
>>> be tricky to do. Unless, you have a solution for that?
>> One possibility is to return the next-state.
>>
>> You could also restrict the possible next states in the table.
>>
>> s0 + e / action_nextstate(s1, s2)
>>
> I implemented action_nextstate, so please take a look.
> It might be checked online HERE ->
> http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO
>
> It's really easy to implement it, the basic idea below.
>
> auto action_nextstate = [](auto... s) {
> std::tuple<decltype(s)...> states{s...};
> return [=](msm::sm<auto>& sm, auto const& evt, bool external_value) {
> action0();
> if (some_guard1(external_value)) {
> action1();
> sm.change_state(std::get<0>(states));
> } else {
> action2(evt);
> sm.change_state(std::get<1>(states));
> }
> };
> };
>
>
> I hope that helps.
I don't know. The syntax is horrible. I would like to be able to use the
states themselves.

std::get<0>(states) doesn't scale.

Passing all the states each time to the action_nextstate will not be the more efficient way.
The states tuple are part of the lambda so the SM will store the tuple of states once for each transition. Even if this is not instantiated for each instance of the SM, this seems unnecessary.

I would suggest to have a single SM context that stores anything needed and let each transition have access to it.

> I do understand your concept, however I'm not sure
> whether such approach
> is the best, but, at least, it's easy to implement. I guess if you can
> prove that this is a common
> case and that performance might be gained using it then it's worth to
> consider such practice in general.

How many times you receive a message and depending on the message
contents and the SM data context your SM will go to one state or another?
I don't know how I could prove that this is quite common, but I can
ensure you that it is ;-)

For performances, there is already the space performances, there is no
need to store local variable on the state machine context, and this can
grow quickly.

For runtime, you avoid calling to process event on each transition
segment, the code of a transition been in a single function the compiler
can inline, optimize, ...

Note that I'm not saying that MSM-lite should not support eUML2 transitions.

Krzysztof Jusiak

unread,
Feb 5, 2016, 3:59:01 PM2/5/16
to bo...@lists.boost.org

>> I do get your point now. It's a valid feature. I added a task to
investigate/implement local transitions. However, I can't promise when the
implementation will be done. Firstly, I have to finish the support for
defering events.


>
>> An internal transition don't exits at all.
>>>
>>> I have no preference for the notation, but why not replace the + sign
>>> with a ^
>>>
>>> src ^ event [guard] / action = src
>>>
>>> src ^ event [guard] / action = src(H)
>>>
>>>
>>> Well, I have just followed MSM approach and '+' was used there and I was
>> fine with it.
>> Is there any reason why '+' is wrong and it should be replaced with '^'
>> instead?
>>
> You misunderstood me. + will represent external transitions, while ^
> could represent local transitions.
>

Yea, I do get it know. Thanks for explanations.

Fair do's, it ain't perfect. However, it doesn't have to be done this way.
I mean, states don't even have to be passed into action_nextState at all,
which makes the implemention clener and easier to follow.
So, the new version would look like that.

auto action_nextstate = [](msm::sm<auto>& sm, auto const& evt, bool


external_value) {
action0();
if (some_guard1(external_value)) {
action1();

fsm(sm).set_current_states("s1"_s);
} else {
action2(evt);
fsm(sm).set_current_states("s2"_s);
}
};

and transition table

return make_transition_table(
*"idle"_s + "event"_t / action_nextstate
, "s1"_s + "event"_t / [] { std::cout << "in s1" << std::endl; }
, "s2"_s + "event"_t / [] { std::cout << "in s2" << std::endl; }
);

BTW. This version is achieved without any changes to the current version of
msm-lite because setting states is done via testing extension.

Working example here -> http://melpon.org/wandbox/permlink/2SJCL6WAK0n9q7bs


>
> I would suggest to have a single SM context that stores anything needed
> and let each transition have access to it.


I don't like 'God objects'. IMHO, it's way better to inject whatever is
required by guards/actions. It's easier to test and maintain it this way
and there is no need for a SM context in the action_nextState example.


> I do understand your concept, however I'm not sure
>> whether such approach
>> is the best, but, at least, it's easy to implement. I guess if you can
>> prove that this is a common
>> case and that performance might be gained using it then it's worth to
>> consider such practice in general.
>>
> How many times you receive a message and depending on the message contents
> and the SM data context your SM will go to one state or another?
> I don't know how I could prove that this is quite common, but I can ensure
> you that it is ;-)
>
> For performances, there is already the space performances, there is no
> need to store local variable on the state machine context, and this can
> grow quickly.
>
> For runtime, you avoid calling to process event on each transition
> segment, the code of a transition been in a single function the compiler
> can inline, optimize, ...
>
> Note that I'm not saying that MSM-lite should not support eUML2
> transitions.


Okay, I see your points. I guess usage of action_nextState might be
justified and might be easily implemented in msm-lite too.

Krzysztof Jusiak

unread,
Feb 5, 2016, 4:30:50 PM2/5/16
to bo...@lists.boost.org
On Fri, Feb 5, 2016 at 5:55 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

> Le 28/01/2016 17:19, Krzysztof Jusiak a écrit :
>
>> Dear Boosters,
>>
>> I have recently released 1.0.0 version of experimental C++14
>> Boost.MSM-lite.
>> Your scalable C++14 header only eUML-like meta state machine library with
>> no dependencies, which outperform Boost.MSM - eUML in:
>> - faster compilation times - up to 60x times faster!
>> - smaller executable size - up to 15x smaller
>> - slightly better performance
>> - smaller memory usage
>> - short error messages
>>
>>
>> Hi,
>
> I have not found anything about how exceptions are managed nor about
> inheritance of state machines. Is there something related to these two
> subjects on your library?
>
>

It's a valid point. Documentation was lacking much info about exceptions
safety. I've just added it here ->
http://boost-experimental.github.io/msm-lite/overview/index.html#exception-safety
Currently, there is no much policy about exception handling though.
However, if guard/action throws state machine will be in a defined state.
Any problems you have encountered with the exceptions? Suggestions are more
than welcome as I'm not sure what would be the best solution here.

Can you elaborate what you mean by `inheritance of state machines`, please?
Is the question related to composite/sub state machines or just whether a
state machine might be inherited?

Best,
> Vicente
>
> P.S. Sorry, I don't know how MSM or statecharts covers these subjects.
>
>

MSM has a policy called `no_exception` which basically disable catching
exceptions. Otherwise they are caught within the process_event.
Don't know how statechart is handling it.

Rob Stewart

unread,
Feb 5, 2016, 5:39:41 PM2/5/16
to bo...@lists.boost.org
On February 4, 2016 5:56:29 AM EST, Kris <krzy...@jusiak.net> wrote:
> On Thu, Feb 4, 2016 at 10:41 AM, Rob Stewart [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
> > On February 3, 2016 3:48:14 PM EST, Kris <[hidden email]
> > <http:///user/SendEmail.jtp?type=node&node=4683202&i=0>> wrote:
> >
> > > There are pre/post fix notations available.
> > > src_state + event [guard] / action = dst_state
> > > or
> > > dst_state <= src_state + event [guard] / action
> >
> > Why = for the one and <= for the other? Can't you use = for both?
>
> The initial idea was to have <= in the prefix notation and => in the
> postfix one. However the latter had to become >= which was quite
> awkward.
> I guess it can be changed into.
>
> dst = src + event [guard] / action
> and
> src + event[guard] / action = dst
>
> I'm just not sure whether this approach is not confusing as we have
> the same syntax for both notations, but sometimes src and sometimes
> dst is used on the left side?
> Do you think, if it possible, it would be better to use = for both
> notations?

It is rather odd to see so much on the left side of the assignment. We're accustomed to the shift operators being used directionally by IOStreams, so what about the following?

dst << src + event [guard] / action
src + event[guard] / action >> dst

[snip quoted snips, signature block, and more]

Please don't quote irrelevant content on this list.

Vicente J. Botet Escriba

unread,
Feb 5, 2016, 7:03:49 PM2/5/16
to bo...@lists.boost.org
Le 05/02/2016 22:30, Krzysztof Jusiak a écrit :
> On Fri, Feb 5, 2016 at 5:55 PM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr> wrote:
>
>> I have not found anything about how exceptions are managed nor about
>> inheritance of state machines. Is there something related to these two
>> subjects on your library?
>>
>>
> It's a valid point. Documentation was lacking much info about exceptions
> safety. I've just added it here ->
> http://boost-experimental.github.io/msm-lite/overview/index.html#exception-safety
> Currently, there is no much policy about exception handling though.
> However, if guard/action throws state machine will be in a defined state.
> Any problems you have encountered with the exceptions?
I'm not yet to the point to try the library. I'm just reading the doc
and asking for things I use to use.

Thanks for the pointer.

With the UML2 transition model is harder to manage with exceptions, as
the next state is on the transition table and the the engine must be
concerned.

I don't understand clearly the different behavior when exceptions
escapes a guard or an action. Changing to the next state could call to
the entry of the state. In any case what you proposes don't allow to
handle the exception at a higher level.


My preference is to go to an associated catch exception 'pseudo state'
and request the process of an associated exception event.

I believe that we could add an associated catch pseudo-state

src_st + event [guard] / action = dst_st|catch_st

When there is an exception on this transition the catch_st is entered
and an exception event is handled.

catch pseudo states can also be associated to an state so that it acts
as the default catch state for all the transitions from this state. We
can see also an upper state as a exception-catcher.

src_st + event [guard] / action = dst_st

If an exception is throw on guard or action, the exception event is
handled on the nesting state of src_st.

The interest of having local transition segments is that the exit of the
current state is not called until there is an external transition segment.

src_st ^ event [guard] / action = dst_st

If an exception is throw on guard or action, the exception event is
handled on src_st.

An exception throw on the dst_st entry should be handled by its nesting
state.

Associating a single TOP level state to a SM allows to associate a catch
state to the SM.

Of course transitions that throw from the catch state associated to the
top level should be transported to the caller or the sender (depending
on whether the mechanism is synchronous or asynchronous).

You can find some descriptions of UML and exception handling e.g. at [1]
for activities or [2]. Look for UML exception handling on your preferred
search engine.


Note that when we use the action_nextstate model, the action_next can
catch the exception and do whatever is needed and possible go to a
specific state after handling the error.

I don't know if all this is compatible with UML2 model, I believe UML2
doesn't model exceptions (C++ exceptions) on guards/actions. There is
the concept of an exception signal, but I'm not sure this respond to
what I'm asking for.


> Suggestions are more
> than welcome as I'm not sure what would be the best solution here.
>
> Can you elaborate what you mean by `inheritance of state machines`, please?
> Is the question related to composite/sub state machines or just whether a
> state machine might be inherited?

A derived state machine can refine a base state machine in different ways:

1* adding new transitions
2* refining a state by adding sub-states and transitions
3* refining the next state of a transition with a sub-state of the
derived next state (or an entry point, but I believe that MSM-lite has
no entry/exit points associated to an state, isn't it?)
4* refining the guard of a transition
5* refining the action of a transition

I'm for at least the 3 first extension mechanisms. The last two can be
emulated with virtual functions.
Point 3* could be not needed if the base class transitions make use of
entry points.


[3] presents an OOHSM with abstract states.


>
> P.S. Sorry, I don't know how MSM or statecharts covers these subjects.
>
>
> MSM has a policy called `no_exception` which basically disable catching
> exceptions. Otherwise they are caught within the process_event.

Do you know what MSM does with the caught exception?


> Don't know how statechart is handling it.
>
>

Vicente

[1] http://edn.embarcadero.com/article/30169
[2]
https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwipzI_H2OHKAhWG2hoKHRHZCuwQFgg3MAI&url=http%3A%2F%2Fwww.mit.bme.hu%2F~pinter%2Fpublications-files%2Fpinter-majzik-2004-fidji-modeling-and-analysis-of-exception-handling-techniques-by-using-uml-statecharts.pdf&usg=AFQjCNEkHdkPZJT2Cn7A8qAyHXJ4W5zcrw&sig2=q5oZ9NfLd7GXnWkFdprb7Q
[3]
https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=7&cad=rja&uact=8&ved=0ahUKEwjxp8qm3-HKAhWGWhQKHdnRA60QFghRMAY&url=http%3A%2F%2Fwww2.ic.uff.br%2F~esteban%2Ffiles%2Fcadabra.pdf&usg=AFQjCNE5KJWQr4m0RB87cgrnKFLDKjBj1A&sig2=uC0-Zikp3OoZVNjzXMUTJw

Krzysztof Jusiak

unread,
Feb 6, 2016, 4:08:19 PM2/6/16
to bo...@lists.boost.org
On Sat, Feb 6, 2016 at 12:03 AM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

Thanks for materials and ideas. It's a really intresesting idea with the
pseudo states. I'm not sure if it is not to complex for msm-lite, but I
will defo take a look.
Your approach also gave me and idea to add exception handling into the
transition table the way events are handled too. Not sure about such
approach, but I guess, it's worth to consider too.

src + event [guard]/action = dst // guard throws runtime_error
src + exception<runtime_error> = X // handle exception

Anyway, I have created a ticket for it here ->
http://boost-experimental.github.io/msm-lite/TODO/index.html


>
> Suggestions are more
>> than welcome as I'm not sure what would be the best solution here.
>>
>> Can you elaborate what you mean by `inheritance of state machines`,
>> please?
>> Is the question related to composite/sub state machines or just whether a
>> state machine might be inherited?
>>
> A derived state machine can refine a base state machine in different ways:
>
> 1* adding new transitions
> 2* refining a state by adding sub-states and transitions
> 3* refining the next state of a transition with a sub-state of the derived
> next state (or an entry point, but I believe that MSM-lite has no
> entry/exit points associated to an state, isn't it?)
>

Not yet, explicit entry/exit points are not supported yet.


> 4* refining the guard of a transition
> 5* refining the action of a transition
>
> I'm for at least the 3 first extension mechanisms. The last two can be
> emulated with virtual functions.
> Point 3* could be not needed if the base class transitions make use of
> entry points.
>
>

Okay, well, msm-lite doesn't support that as a feature. However, you can
achieve more or less all of mentioned things just by using C++.
For example, you can extend transiton table of a state machine by joining
it with another one.

auto table1 = make_transition_table(transitions...);
auto table2 = make_transition_table(table1, other_transitions...);


> [3] presents an OOHSM with abstract states.
>
>>
>> P.S. Sorry, I don't know how MSM or statecharts covers these subjects.
>>
>>
>> MSM has a policy called `no_exception` which basically disable catching
>> exceptions. Otherwise they are caught within the process_event.
>>
> Do you know what MSM does with the caught exception?


By default assert will be called, but you can override the default
behaviour by adding your custom handler to the state machine.

template <class FSM,class Event>
void exception_caught (Event const&,FSM&,std::exception& ) {
... // handle exception here

Kris

unread,
Feb 6, 2016, 4:23:58 PM2/6/16
to bo...@lists.boost.org
On Fri, Feb 5, 2016 at 10:15 PM, Rob Stewart [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> On February 4, 2016 5:56:29 AM EST, Kris <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4683264&i=0>> wrote:
>
> > On Thu, Feb 4, 2016 at 10:41 AM, Rob Stewart [via Boost] <
> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683264&i=1>>
Yea, shift operators are symmetrical, which is awesome. I don't find them
odd and I have even tried them at some point in the past.
However, I have encountered one ackward thing with the usage of them with
data events.

src + event<some_event_data> >> dst // '> >>' is quite unfortunate
combination here

All in all, I'm not sure which syntax would be the best in the end.
On the one hand, '<-' and '->' would be perfect, but can't be done with
operators. On the other hand, '=', '=' is short and sweat, but might be a
bit confusing.
Finally, '<<', '>>' is symetric, but sometimes a bit ackward.

Any suggestions, which one would be the best? Right now, I'm thinking '='
is the best choice, but maybe it would be best to give user a final
decision? Not sure.


> [snip quoted snips, signature block, and more]
>
> Please don't quote irrelevant content on this list.
>
> ___
> Rob
>
> (Sent from my portable computation engine)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683264.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683292.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 6, 2016, 5:58:06 PM2/6/16
to bo...@lists.boost.org
Le 06/02/2016 22:07, Krzysztof Jusiak a écrit :
> On Sat, Feb 6, 2016 at 12:03 AM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr> wrote:
>
>> Le 05/02/2016 22:30, Krzysztof Jusiak a écrit :
>>
> Thanks for materials and ideas. It's a really intresesting idea with the
> pseudo states. I'm not sure if it is not to complex for msm-lite, but I
> will defo take a look.
> Your approach also gave me and idea to add exception handling into the
> transition table the way events are handled too. Not sure about such
> approach, but I guess, it's worth to consider too.
>
> src + event [guard]/action = dst // guard throws runtime_error
> src + exception<runtime_error> = X // handle exception
Yes, this is the idea.
This should respond to point 1*. 2* should need to replace the refined
state in table1.
Point 3 would covered if the make_transition_table function overrides
the redefined transitions.

It would be great if you show how the user can address these points with
your library using some run-able concrete examples.

Vicente

Rob Stewart

unread,
Feb 7, 2016, 12:25:09 PM2/7/16
to bo...@lists.boost.org
On February 6, 2016 3:59:30 PM EST, Kris <krzy...@jusiak.net> wrote:
>
> I have encountered one ackward thing with the usage of [shift
> operators] with data events.
>
> src + event<some_event_data> >> dst // '> >>' is quite unfortunate
> combination here

How ironic. We got a new rule in the language to allow for multiple >'s to be considered template argument list delimiters, but it won't help here. Such are the problems of EDSLs.

So far, we have these options:

1)
d = s + e[g]/a
s + e[g]/a = d

2)
d << s + e[g]/a
s + e[g]/a >> d

The choices are limited. Another pair that comes to mind is <= and ->.

3)
d <= s + e[g]/a
s + e[g]/a -> d

Those are directional and the = vs. - asymmetry might be a good thing.

The last pair I can suggest is the following:

4)
d = s + e[g]/a
s + e[g]/a -> d

1) is strange given that we expect assignment to be to the expression on the LHS.

2) has the template argument list and shift operator parsing issue. I always put a space on either side of binary operators, so that wouldn't actually affect me.

3) is only troubling due to the asymmetry in the number of lines between = and -.

4) involves normal assignment semantics in the one case and evokes the new return type function syntax in the other.

The imbalance between the syntaxes for 3) and 4) may not be a big deal since users will adopt one or the other. An issue arises when reading our maintaining the code of someone using the opposite syntax, of course.

My favorite of these is 2).

Kris

unread,
Feb 8, 2016, 2:57:52 PM2/8/16
to bo...@lists.boost.org
On Sat, Feb 6, 2016 at 10:34 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> Le 06/02/2016 22:07, Krzysztof Jusiak a écrit :
>
> > On Sat, Feb 6, 2016 at 12:03 AM, Vicente J. Botet Escriba <

> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683294&i=0>>


> wrote:
> >
> >> Le 05/02/2016 22:30, Krzysztof Jusiak a écrit :
> >>
> > Thanks for materials and ideas. It's a really intresesting idea with the
> > pseudo states. I'm not sure if it is not to complex for msm-lite, but I
> > will defo take a look.
> > Your approach also gave me and idea to add exception handling into the
> > transition table the way events are handled too. Not sure about such
> > approach, but I guess, it's worth to consider too.
> >
> > src + event [guard]/action = dst // guard throws runtime_error
> > src + exception<runtime_error> = X // handle exception
> Yes, this is the idea.


Great. I have improved error handling if it comes to exceptions.
Right now, if you do NOT compile with `-fno-exceptions` and do not specify
configure noexcept then you can handle any exceptions thrown on the
transition table.

make_transition_table(
*"idle"_s + "event1"_t / [] { throw std::runtime_error{"error"}; }
, "idle"_s + "event2"_t / [] { throw 0; }

, *"error_handling"_s + exception<std::runtime_error> / [] { std::cout <<
"exception caught" << std::endl; }
, "error_handling"_s + exception<> / [] { std::cout << "generic
exception caught, terminate..." << std::endl; } = X
);

You can handle specific type of the exception(exception<type>) or just
any(exception<>).

Improved documentation and examples here:
*
http://boost-experimental.github.io/msm-lite/overview/index.html#exception-safety
*
http://boost-experimental.github.io/msm-lite/tutorial/index.html#8-error-handling

*
http://boost-experimental.github.io/msm-lite/examples/index.html#error-handling

I was wondering whether your point with extending transitions can't be
achieved using sub machines instead ? For example.

struct example {
auto configure() const noexcept {
using namespace msm;
return make_transition_table(
*"idle"_s + event<e1> / [] { std::cout << "in sub sm" << std::endl;
} = "s1"_s
, "s1"_s + event<e2> / [] { std::cout << "finish sub sm" <<
std::endl; } = X
);
}
};

struct extend_example
auto configure() const noexcept {
using namespace msm;
state<sm<example>> composite;
return make_transition_table(
*composite = composite // composite region
//-----------------------------------//
// add new transitions for error handling
, *"error_handling"_s + unexpected_event<> / [] { std::cout <<
"unexpected event, terminate..." << std::endl; } = X
, "error_handling"_s + exception<std::runtime_error> / [] { std::cout
<< "exception caught" << std::endl; }
, "error_handling"_s + exception<> / [] { std::cout << "generic
exception caught, terminate..." << std::endl; } = X
);
}
};

Right now,
sm<example> sm;
sm.process_event(e1{}); // handled by example
sm.process_event(e2{}); // handled by example
sm.process_event(e3{}); // handled by extended_example error handling


>
> It would be great if you show how the user can address these points with
> your library using some run-able concrete examples.
>

Yea, I will work on that. Cheers for the pointers.


> Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683294.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683329.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Kris

unread,
Feb 8, 2016, 4:12:51 PM2/8/16
to bo...@lists.boost.org
On Sun, Feb 7, 2016 at 5:01 PM, Rob Stewart [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> On February 6, 2016 3:59:30 PM EST, Kris <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=4683304&i=0>> wrote:
> >
> > I have encountered one ackward thing with the usage of [shift
> > operators] with data events.
> >
> > src + event<some_event_data> >> dst // '> >>' is quite unfortunate
> > combination here
>
> How ironic. We got a new rule in the language to allow for multiple >'s to
> be considered template argument list delimiters, but it won't help here.
> Such are the problems of EDSLs.
>
>
Heheh, true that.


> So far, we have these options:
>
> 1)
> d = s + e[g]/a
> s + e[g]/a = d
>
> 2)
> d << s + e[g]/a
> s + e[g]/a >> d
>
> The choices are limited. Another pair that comes to mind is <= and ->.
>
> 3)
> d <= s + e[g]/a
> s + e[g]/a -> d
>
> Those are directional and the = vs. - asymmetry might be a good thing.
>

That's is a winner for me! However, I don't think it is possible to
implement, is it?
`->` is not really user friendly for writing DSLs.

Or maybe, like that, but that is even harder to achieve.

d <- s + e[g]/a
s + e[g]/a -> d


>
> The last pair I can suggest is the following:
>
> 4)
> d = s + e[g]/a
> s + e[g]/a -> d


> 1) is strange given that we expect assignment to be to the expression on
> the LHS.
>

Yea, its a fair point. '<<', '<-' seems to be better for the dst - src
option.


>
> 2) has the template argument list and shift operator parsing issue. I
> always put a space on either side of binary operators, so that wouldn't
> actually affect me.
>

I like this option, but I find it extremly ackward to have following
notation - src + exception<std::runtime_error> >> dst


>
> 3) is only troubling due to the asymmetry in the number of lines between =
> and -.
>

Yea, it's defo a decent option. I would gladly choose this option, but I
don't think '->' is easy to achieve.


>
> 4) involves normal assignment semantics in the one case and evokes the new
> return type function syntax in the other.
>
> True.


> The imbalance between the syntaxes for 3) and 4) may not be a big deal
> since users will adopt one or the other. An issue arises when reading our
> maintaining the code of someone using the opposite syntax, of course.
>
> My favorite of these is 2).
>

Thank you for the analysis. It's extremely useful. IMHO

s + e[g]/a ->d

is the winner for the postfix notation as it follows UML notation and has a
direction. However, I don't think is achievable. Well, at least I don't
have any idea how to do it :(

If it comes to the prefix notation, I guess, '<=', "<<" are the options to
choose from.

I will try to work on '->', maybe it's possible, it is C++ in the end.


> ___
> Rob
>
> (Sent from my portable computation engine)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683304.html
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683330.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente J. Botet Escriba

unread,
Feb 9, 2016, 12:38:04 PM2/9/16
to bo...@lists.boost.org
Le 08/02/2016 20:32, Kris a écrit :
> On Sat, Feb 6, 2016 at 10:34 PM, Vicente Botet [via Boost] <
> ml-node+s2283...@n4.nabble.com> wrote:
>
>> src + event [guard]/action = dst // guard throws runtime_error
>> src + exception<runtime_error> = X // handle exception
>> Yes, this is the idea.
>
> Great. I have improved error handling if it comes to exceptions.
> Right now, if you do NOT compile with `-fno-exceptions` and do not specify
> configure noexcept then you can handle any exceptions thrown on the
> transition table.
>
> make_transition_table(
> *"idle"_s + "event1"_t / [] { throw std::runtime_error{"error"}; }
> , "idle"_s + "event2"_t / [] { throw 0; }
>
> , *"error_handling"_s + exception<std::runtime_error> / [] { std::cout <<
> "exception caught" << std::endl; }
> , "error_handling"_s + exception<> / [] { std::cout << "generic
> exception caught, terminate..." << std::endl; } = X
> );
I missed the syntax for the orthogonal regions. It is not very explicit.
The idea to have an orthogonal section that does the error handling is
good, but how would you do error recovery?

I don't think you should correlate whether MSM manage exceptions and
whether the configure function is noexcept.

When you say " When guard/action throws an exception State Machine
<http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-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.

> You can handle specific type of the exception(exception<type>) or just
> any(exception<>).
What would be the event associated to the action in this cases?
>
>>> Okay, well, msm-lite doesn't support that as a feature. However, you can
>>> achieve more or less all of mentioned things just by using C++.
>>> For example, you can extend transiton table of a state machine by
>> joining
>>> it with another one.
>>>
>>> auto table1 = make_transition_table(transitions...);
>>> auto table2 = make_transition_table(table1, other_transitions...);
>>>
>> This should respond to point 1*. 2* should need to replace the refined
>> state in table1.
>> Point 3 would covered if the make_transition_table function overrides
>> the redefined transitions.
>>
> I was wondering whether your point with extending transitions can't be
> achieved using sub machines instead ?
This is another mechanism of extension that of course should work also,
but that is not related to the previous 5 extensions mechanisms

>> It would be great if you show how the user can address these points with
>> your library using some run-able concrete examples.
>>
> Yea, I will work on that. Cheers for the pointers.
>
>
Thanks for working on this.

Kris

unread,
Feb 9, 2016, 3:44:41 PM2/9/16
to bo...@lists.boost.org
On Tue, Feb 9, 2016 at 5:13 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> 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:
> >
> >> src + event [guard]/action = dst // guard throws runtime_error
> >> src + exception<runtime_error> = X // handle exception
> >> Yes, this is the idea.
> >
> > Great. I have improved error handling if it comes to exceptions.
> > Right now, if you do NOT compile with `-fno-exceptions` and do not
> specify
> > configure noexcept then you can handle any exceptions thrown on the
> > transition table.
> >
> > make_transition_table(
> > *"idle"_s + "event1"_t / [] { throw std::runtime_error{"error"}; }
> > , "idle"_s + "event2"_t / [] { throw 0; }
> >
> > , *"error_handling"_s + exception<std::runtime_error> / [] {
> std::cout <<
> > "exception caught" << std::endl; }
> > , "error_handling"_s + exception<> / [] { std::cout << "generic
> > exception caught, terminate..." << std::endl; } = X
> > );
> I missed the syntax for the orthogonal regions. It is not very explicit.


Well, you can make it more explicit if you wish by changing the syntax a bit

(*"idle"_s) + "event1"_t / [] { throw std::runtime_error{"error"}; }


, "idle"_s + "event2"_t / [] { throw 0; }

//---------------------------------------------------------------------------------------------------------/
, (*"error_handling"_s) + exception<std::runtime_error> / [] { }


> The idea to have an orthogonal section that does the error handling is
> good, but how would you do error recovery?
>
>

Well, it depends whether you have to or not recover out of it. If you
don't, another orthogonal region which will do the cleanup is good enough.
However, if you do have to recover I would use another state for it, as you
suggested.

make_transition_table(
(*"idle"_s) + "event1"_t / [] { throw std::runtime_error{"error"}; }


, "idle"_s + "event2"_t / [] { throw 0; }

, "idle"_s + exception<std::runtime_error> / [] { ... } = "recover"_s
, "recover"_s + "okay"_t = "idle"_s // fine now
);

> 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.

> When you say " When guard/action throws an exception State Machine

> <<a href="
> http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-state-machine


> ">
> http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-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

>
> > You can handle specific type of the exception(exception<type>) or just
> > any(exception<>).
> What would be the event associated to the action in this cases?
>
>

Simply, none. It won't compile when you try to add action/guard with the
event for this transition.
In case of exception<>:

auto guard = [] (auto event) {} // won't compile
auto guard = [] () {} // okay

However, you can get some info about the exception using
std::current_exception

auto action = [] () {
auto exptr = std::current_exception();
...
}

>
> >>> Okay, well, msm-lite doesn't support that as a feature. However, you
> can
> >>> achieve more or less all of mentioned things just by using C++.
> >>> For example, you can extend transiton table of a state machine by
> >> joining
> >>> it with another one.
> >>>
> >>> auto table1 = make_transition_table(transitions...);
> >>> auto table2 = make_transition_table(table1, other_transitions...);
> >>>
> >> This should respond to point 1*. 2* should need to replace the refined
> >> state in table1.
> >> Point 3 would covered if the make_transition_table function overrides
> >> the redefined transitions.
> >>
> > I was wondering whether your point with extending transitions can't be
> > achieved using sub machines instead ?
> This is another mechanism of extension that of course should work also,
> but that is not related to the previous 5 extensions mechanisms
>
> >> It would be great if you show how the user can address these points
> with
> >> your library using some run-able concrete examples.
> >>
> > Yea, I will work on that. Cheers for the pointers.
> >
> >
> Thanks for working on this.
>

Np


> Vicente
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683364.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683369.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Vicente J. Botet Escriba

unread,
Feb 9, 2016, 6:00:27 PM2/9/16
to bo...@lists.boost.org
Le 09/02/2016 21:19, Kris a écrit :
> On Tue, Feb 9, 2016 at 5:13 PM, Vicente Botet [via Boost] <
> ml-node+s2283...@n4.nabble.com> 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?

>
>
>
>> When you say " When guard/action throws an exception State Machine
>> <<a href="
>> http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-state-machine
>> ">
>> http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-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.


>>> You can handle specific type of the exception(exception<type>) or just
>>> any(exception<>).
>> What would be the event associated to the action in this cases?
>>
>>
> Simply, none. It won't compile when you try to add action/guard with the
> event for this transition.
> In case of exception<>:
>
> auto guard = [] (auto event) {} // won't compile
> auto guard = [] () {} // okay
>
> However, you can get some info about the exception using
> std::current_exception
>
> auto action = [] () {
> auto exptr = std::current_exception();
> ...
> }
>
>

Yes this should work.

Krzysztof Jusiak

unread,
Feb 10, 2016, 5:52:02 AM2/10/16
to bo...@lists.boost.org
On Tue, Feb 9, 2016 at 11:00 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> 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+s2283...@n4.nabble.com> 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 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. One doesn't
have to deal with undefined states .
Just for the record, Boost.MSM has a policy to set when change state should
happen.

Vicente J. Botet Escriba

unread,
Feb 10, 2016, 12:11:33 PM2/10/16
to bo...@lists.boost.org
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.

>>> When you say " When guard/action throws an exception State Machine
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.

https://en.wikipedia.org/wiki/UML_state_machine#Transition_execution_sequence

> 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?

Best,

Krzysztof Jusiak

unread,
Feb 10, 2016, 4:07:58 PM2/10/16
to bo...@lists.boost.org
On Wed, Feb 10, 2016 at 5:11 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

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.


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.


>
>
> 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 ->
http://www.boost.org/doc/libs/1_57_0/libs/msm/doc/HTML/ch03s05.html#d0e2714

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

Vicente J. Botet Escriba

unread,
Feb 11, 2016, 7:28:31 AM2/11/16
to bo...@lists.boost.org
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 ->
> http://www.boost.org/doc/libs/1_57_0/libs/msm/doc/HTML/ch03s05.html#d0e2714
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.

Krzysztof Jusiak

unread,
Feb 12, 2016, 6:22:08 AM2/12/16
to bo...@lists.boost.org
On Thu, Feb 11, 2016 at 12:28 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:


I checked UML2.5 specification and I have found "Transition execution
sequence" (14.2.3.9.6 / page 316).
However, there is no much info about the sequence there. It's mostly about
that exit of the main state has to happen before entry to the target state.
I can't find anything about when guard/action should happen in the sequence
:/ buy it's a long document so maybe it might be found somewhere?


>
> 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.


Yea, I do get it. Cheers. Do have any example when local transitions are
useful? I see some usage for them but I struggle really to find a really
good use case for them.

Vicente J. Botet Escriba

unread,
Feb 12, 2016, 1:44:56 PM2/12/16
to bo...@lists.boost.org
Le 12/02/2016 12:20, Krzysztof Jusiak a écrit :
> On Thu, Feb 11, 2016 at 12:28 PM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr> wrote:
>
>>
>> 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.
>
> I checked UML2.5 specification and I have found "Transition execution
> sequence" (14.2.3.9.6 / page 316).
> However, there is no much info about the sequence there. It's mostly about
> that exit of the main state has to happen before entry to the target state.
> I can't find anything about when guard/action should happen in the sequence
> :/ buy it's a long document so maybe it might be found somewhere?
>
On page 377 I see an example where the order is clear

xS11; t1; xS1; t2; eT1; eT11; t3; eT111

Where xAAA means exit action on state AAA and eAAA entry on state AAA.
ti are actions on the segmented transitions.

Just before this example you can find

*"Transition execution sequence **
*Every Transition, except for internal and local Transitions, causes
exiting of a source State, and entering of the target State. These two
States, which may be composite, are designated as the main source and
the main target of a Transition respectively.
The main source is a direct substate of the Region that contains the
source States, and the main target is the substate of the Region that
contains the target States.
NOTE. A Transition from one Region to another in the same immediate
enclosing composite State is not allowed. Once a Transition is enabled
and is selected to fire, the following steps are carried out in order:
1. Starting with the main source State, the States that contain the main
source State are exited according to the rules of State exit (or,
composite State exit if the main source State is nested) as described
earlier.
2. The series of State exits continues until the first Region that
contains, directly or indirectly, both the main source and main target
states is reached. The Region that contains both the main source and
main target states is called their least common ancestor. At that point,
the effect Behavior of the Transition that connects the
sub-configuration of source States to the sub-configuration of target
States is executed. (A “sub-configuration” here refers to that subset of
a full state configuration contained within the least common ancestor
Region.)
3. The configuration of States containing the main target State is
entered, starting with the outermost State in the least common ancestor
Region that contains the main target State. The execution of Behaviors
follows the rules of State entry (or composite State entry) described
earlier. "

I believe this is clear enough.
1 exits
2 action
3 entries


>> 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.
>
> Yea, I do get it. Cheers. Do have any example when local transitions are
> useful? I see some usage for them but I struggle really to find a really
> good use case for them.
>
>
>

Let say that you have a state S with two sub-states S1 and S2.
While in state S, if you receive the event E1 you want to go to S1, but
don't want to execute the exit of state S. However you want to execute
the exit of S1 or S2.

S ^ E1 = S1;

Think of E1 as an event that interrupts whatever you were doing on S1 or S2.

Krzysztof Jusiak

unread,
Feb 15, 2016, 5:08:32 AM2/15/16
to bo...@lists.boost.org
On Fri, Feb 12, 2016 at 6:44 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:


For me it is semi clear, but I do agree with your conclusion though.
However, there is no info about guards being executed before src state exit.
It might be implied by the statement that transition has to be enabled, but
I'm not sure about it.


>
>
> 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.
>>>
>>
>> Yea, I do get it. Cheers. Do have any example when local transitions are
>> useful? I see some usage for them but I struggle really to find a really
>> good use case for them.
>>
>>
>>
>> Let say that you have a state S with two sub-states S1 and S2.
> While in state S, if you receive the event E1 you want to go to S1, but
> don't want to execute the exit of state S. However you want to execute the
> exit of S1 or S2.
>
> S ^ E1 = S1;
>
> Think of E1 as an event that interrupts whatever you were doing on S1 or
> S2.
>
>

Yea, yea I do get that. I was asking more about real life example. I mean,
what use case would require such behavior, because I can't think of any,
but I know there are some.
I'm asking because I don't have any experience with local transition and it
is hard to justify adding a new feature without a meaningful rationale.

Thank you for you feedback, it is very useful.

Vicente J. Botet Escriba

unread,
Feb 15, 2016, 7:17:45 AM2/15/16
to bo...@lists.boost.org
Le 15/02/2016 11:08, Krzysztof Jusiak a écrit :
> On Fri, Feb 12, 2016 at 6:44 PM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr> wrote:
>
>> Le 12/02/2016 12:20, Krzysztof Jusiak a écrit :
>>
>
> For me it is semi clear, but I do agree with your conclusion though.
> However, there is no info about guards being executed before src state exit.
> It might be implied by the statement that transition has to be enabled, but
> I'm not sure about it.
>

Yes, I believe that event reception and the guard evaluation are the enablers of the transition.

Let say that we are on a disabled state. In this state you have
sub-states representing the path to go to another enabled state (e.g.
requesting a password, ...) .
If you receive a reset event this would disable any trial to go to the
enabled state.
From the disabled state you could have a local transition when
receiving this reset event and go to the sub-state disabled/idle.
What is important is that you are always in the disabled state, so the
disabled exit has not been executed.

Krzysztof Jusiak

unread,
Feb 16, 2016, 11:45:20 AM2/16/16
to bo...@lists.boost.org
On Mon, Feb 15, 2016 at 12:17 PM, Vicente J. Botet Escriba <
vicent...@wanadoo.fr> wrote:

> Le 15/02/2016 11:08, Krzysztof Jusiak a écrit :
>
>> On Fri, Feb 12, 2016 at 6:44 PM, Vicente J. Botet Escriba <
>> vicent...@wanadoo.fr> wrote:
>>
>> Le 12/02/2016 12:20, Krzysztof Jusiak a écrit :
>>>
>>>
>> For me it is semi clear, but I do agree with your conclusion though.
>> However, there is no info about guards being executed before src state
>> exit.
>> It might be implied by the statement that transition has to be enabled,
>> but
>> I'm not sure about it.
>>
>>
> Yes, I believe that event reception and the guard evaluation are the
> enablers of the transition.
>
>

Yea, but that would mean that guard has to be evaluated before exit of the
state or any action, so the order would be.

1. guard [to enable transition]
2. exit src state
3. actions...
4. entry dst state

When the actual state change should happen in above sequence it's not
stated in the document as well.

I would assume following order according to the spec + a bit of rationality?

1. guard [to enable transition]
2. exit src state
3. actions...
4. CHANGE THE STATE TO DST HERE?
5. entry dst state

Cheers, it helps a lot.

Vicente J. Botet Escriba

unread,
Feb 16, 2016, 5:16:09 PM2/16/16
to bo...@lists.boost.org
Le 16/02/2016 17:44, Krzysztof Jusiak a écrit :
> Yea, but that would mean that guard has to be evaluated before exit of the
> state or any action, so the order would be.
>
> 1. guard [to enable transition]
> 2. exit src state
> 3. actions...
> 4. entry dst state
>
> When the actual state change should happen in above sequence it's not
> stated in the document as well.
>
> I would assume following order according to the spec + a bit of rationality?
>
> 1. guard [to enable transition]
> 2. exit src state
> 3. actions...
> 4. CHANGE THE STATE TO DST HERE?
> 5. entry dst state
>
I agree. It was evident to me, but I can not point to any wording.

Kris

unread,
Feb 17, 2016, 10:45:53 AM2/17/16
to bo...@lists.boost.org
On Tue, Feb 16, 2016 at 9:50 PM, Vicente Botet [via Boost] <
ml-node+s2283...@n4.nabble.com> wrote:

> Le 16/02/2016 17:44, Krzysztof Jusiak a écrit :
>
> > Yea, but that would mean that guard has to be evaluated before exit of
> the
> > state or any action, so the order would be.
> >
> > 1. guard [to enable transition]
> > 2. exit src state
> > 3. actions...
> > 4. entry dst state
> >
> > When the actual state change should happen in above sequence it's not
> > stated in the document as well.
> >
> > I would assume following order according to the spec + a bit of
> rationality?
> >
> > 1. guard [to enable transition]
> > 2. exit src state
> > 3. actions...
> > 4. CHANGE THE STATE TO DST HERE?
> > 5. entry dst state
> >
> I agree. It was evident to me, but I can not point to any wording.
>

Great to hear that. However, above sequence makes exception handling a bit
harder as
with guards we haven't left the src state but with actions we started the
exit already.

1. When exception happens in a guard
* src state is unchanged

2. When exception happens in an action
* src state is exited

Moreover, following below sequence

3. actions...
4. CHANGE THE STATE TO DST HERE?

makes it harder to process internal events

"src"_s + event / process_event(other_event) = "dst"_s
, "src"_s + other_event = X // most likely, should be this one as we
haven't changed the state yet?
, "dst"_s + other_event = X

and, therefore, maybe it's better to have it the other way around?

3. CHANGE THE STATE TO DST HERE?
4. actions...

Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>

> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683550.html


--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683585.html


Sent from the Boost - Dev mailing list archive at Nabble.com.

_______________________________________________

Vicente J. Botet Escriba

unread,
Feb 17, 2016, 12:46:47 PM2/17/16
to bo...@lists.boost.org

I have never used process_event in an action on the same state machine
(You are re-entering the state machine :( ). The single think you can do
is to post it (push in a queue) or call process_event in another state
machine. However you must ensure the there are no cycles. The
asynchronous way avoids always the possible cycles.

In some projects I have defined a hierarchy of state machines and the
upper layer state machines use synchronous communication to communicate
to lower state machines and the reverse, lower layer use always
asynchronous communication with upper layer state machines (half
sync/half async).

There are 3 features that I'm missing in UML state machines that I found
in SDL [1]. Maybe these features have no sense with synchronous state
machines.

* Procedures that can contain states. The difference with nested states
is that procedures are stack based and return to the point of call when
the procedure terminates. You can reuse a procedure inside a state
machine several times of course.
* Synchronous Remote Procedures that allows to do a call/replay at once.
This avoids the use of wait states on which the every other event tan
the replay is deferred.
* Synchronous Remote Variables that allows to read a remote variable.The
same here; but just to query for the value of a remote variable.

Vicente

[1]
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&uact=8&ved=0ahUKEwi1vqWwqP_KAhUGWhoKHa-DB3oQFghEMAQ&url=http%3A%2F%2Fwww.itu.int%2FITU-T%2Fstudygroups%2Fcom10%2Flanguages%2FZ.100_1199.pdf&usg=AFQjCNFwOMg8j5RuW77nxtjPuj3c8eq2mQ&sig2=svSxdC5kgb1EBGDbnchYwg
[2] https://fr.wikipedia.org/wiki/Specification_and_Description_Language

Krzysztof Jusiak

unread,
Feb 18, 2016, 12:41:29 PM2/18/16
to bo...@lists.boost.org

It's a great point! To be honest with you, I have never liked process_event
on the transition table, however, I blindly followed MSM approach (fsm is
always passed to guards/actions in MSM, so you can do whatever) but it's a
bit dangerous here, as you mentioned. I'm going to change that to support
only defer or queue events on the transition table. Thanks for your input
on that, makes complete sense.


>
> In some projects I have defined a hierarchy of state machines and the
> upper layer state machines use synchronous communication to communicate to
> lower state machines and the reverse, lower layer use always asynchronous
> communication with upper layer state machines (half sync/half async).


> There are 3 features that I'm missing in UML state machines that I found
> in SDL [1]. Maybe these features have no sense with synchronous state
> machines.
>
> * Procedures that can contain states. The difference with nested states is
> that procedures are stack based and return to the point of call when the
> procedure terminates. You can reuse a procedure inside a state machine
> several times of course.
> * Synchronous Remote Procedures that allows to do a call/replay at once.
> This avoids the use of wait states on which the every other event tan the
> replay is deferred.
> * Synchronous Remote Variables that allows to read a remote variable.The
> same here; but just to query for the value of a remote variable.
>

> Thanks for the links. I have never seen SDL before, it looks really
interesting. A lot of new concepts for me. I know that, Christophe (author
of MSM) was working on asynchronous library and integration it with MSM,
however, I'm not sure about the status. Anyway, it's a good learning to
follow. Cheers for that. Definitely a lot of stuff to implement in the
future!

Reply all
Reply to author
Forward
0 new messages