Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guard language and general question #23

Open
x37v opened this issue Oct 15, 2021 · 7 comments
Open

Guard language and general question #23

x37v opened this issue Oct 15, 2021 · 7 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@x37v
Copy link
Contributor

x37v commented Oct 15, 2021

the README states:

A guard is a function which returns true if the state transition should happen, and false if the transition should not happen, 

But in the examples we see that guards return Result<(), ()>.. functionally I guess they're the same except I see that you can return a custom error instead of (). But, re my question below, depending on the goal of a guard, an Err(()) might feel a little wrong?

I'm wondering what the general idea for a guard is? I'm assuming it is a way to encapsulate some functionality so that Event data can be evaluated and instead of having ButtonSevenDown you can have Button { down: true, index: 7 } and evaluate the a guard button_down, button_seven_down or button_seven ?

@x37v
Copy link
Contributor Author

x37v commented Oct 20, 2021

I think my confusion around guards is because transitioning from the same state, with the same event but different guards isn't legal:

statemachine! {
    transitions: {
        *State1 + Event1(MyEventData) [guard1] / action1 = State2,
        State1 + Event1(MyEventData) [guard2] / action1 = State4,
    }
}

but if you look at the boost action-guards
example you can see that in their setup, it would be:

...
      , "s3"_s + event<e4> [ !guard1 || guard2 ] / (action1, [] { std::cout << "action3" << std::endl; }) = "s4"_s
      , "s3"_s + event<e4> [ guard1 ] / ([] { std::cout << "action4" << std::endl; }, [this] { action4(); } ) = "s5"_s
...

@dzimmanck
Copy link
Collaborator

@x37v, I looked at both of your comments and would like to summarize the 3 options you touch on.

  1. We add support for guards to specified combinatorically matching the boost syntax.
  2. We add support for guards to be specified with pattern matching, effectively turning them into different guards.
  3. We add support for a new guard syntax in the style used by Rust pattern matching that allows logic.

The issue I see here will be around error checking. The main reason to NOT allow 2 transitions with the same starting state and event and different guards is that if both guards are true, you can have can have a transition table with a conflicting output state. Given that this crate was originally designed to mimic the boost syntax, I think it makes sense to mimic it where features overlap. This syntax basically allows for an event to be re-used with different logical combinations of guards, forcing the user to explicitly specify a mutually exclusive transition.

@x37v
Copy link
Contributor Author

x37v commented Jan 7, 2022

The main reason to NOT allow 2 transitions with the same starting state and event and different guards is that if both guards are true, you can have can have a transition table with a conflicting output state.

Yeah.. I have a fork that allows for this and there is an implicit behavior that the first valid transition takes precedence (as it is just a match)

@dzimmanck
Copy link
Collaborator

@x37v, why not do a PR? Its new syntax that is useful that is a user is not required to use.

@dzimmanck
Copy link
Collaborator

I do think the Rust style match guard is the most elegant approach, although definitely not what boost uses.

@x37v
Copy link
Contributor Author

x37v commented Jan 7, 2022

@x37v, why not do a PR? Its new syntax that is useful that is a user is not required to use.

it is quite a departure: https://github.com/x37v/smlang-rs

@dzimmanck dzimmanck added enhancement New feature or request question Further information is requested labels Jan 10, 2022
@corecode
Copy link

Multiple transitions with same state/event combination but different guards is important for versatility. Otherwise a user needs to expand what a guard could handle into separate events, which can lead to code duplication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants