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

Conditional branching #13

Closed
piotrmurach opened this issue May 18, 2014 · 7 comments
Closed

Conditional branching #13

piotrmurach opened this issue May 18, 2014 · 7 comments

Comments

@piotrmurach
Copy link
Owner

@kjwierenga As requested in this issue I came around to think that this should be implemented. My current thoughts on semantics would be to allow specifying branch states as an array, like so:

event :next, :company_form => [:agreement_form,:promo_form],
              if: -> (registrant, user) { user.has_promo? }

Depending on the event condition we would choose appropriate state. One important question to ask is how to distinguish between event conditional logic and state condition. Currently the :if/:unless allow you to guard the transition, that is, ensure the transition succeeds or fails. However, the branching condition would allow to choose between possible states, e.i. it would always succeed. One suggestion would be to use another key argument

event :next, :company_form => [:agreement_form,:promo_form],
              branch: -> (registrant, user) { user.has_promo? }

Any thoughts?

@kjwierenga
Copy link

What you’re describing is called a choice pseudo state (as described here http://www.uml-diagrams.org/state-machine-diagrams.html#choice-pseudostate).

As you point out a conditional transition is different from a choice pseudo state. I concur your choice for a name different to :if/:unless. Maybe :choice?

What is unclear in your proposed syntax is how the array maps to truth values of the condition. If you decide to implement this you should also think ahead about having more than two results and handling the else case when none of the conditions are met.

Another way to implement this kind of behaviour is to define different events for each condition, This could be the pragmatic solution, although it means not all behaviour is defined in the state machine.

Op 18 mei 2014, om 22:45 heeft Piotr Murach notifications@github.com het volgende geschreven:

@kjwierenga As requested in this issue I came around to think that this should be implemented. My current thoughts on semantics would be to allow specifying branch states as an array, like so:

event :next, :company_form => [:agreement_form,:promo_form],
if: -> (registrant, user) { user.has_promo? }
Depending on the event condition we would choose appropriate state. One important question to ask is how to distinguish between event conditional logic and state condition. Currently the :if/:unless allow you to guard the transition, that is, ensure the transition succeeds or fails. However, the branching condition would allow to choose between possible states, e.i. it would always succeed. One suggestion would be to use another key argument

event :next, :company_form => [:agreement_form,:promo_form],
branch: -> (registrant, user) { user.has_promo? }
Any thoughts?


Reply to this email directly or view it on GitHub.

@piotrmurach
Copy link
Owner Author

I like the word :choice, especially for multiple conditions. Tentatively, I would propose to do

event :next do
  choice :company_form => :agreement_form, :if ....
  choice :company_form => :promo_form, :if ....
  choice :company_form => :official_form, :if ....
  default :promo_form
end

The first condition that matches is the transition that is performed. Otherwise the default state is set. This would mean the if/unless can be reused in the conditional pseudo state implementation. Thoughts?

@kjwierenga
Copy link

And how would this look if I didn’t want to use a block? Or should you move the from state (:company_form) outside the block?

Op 19 mei 2014, om 15:01 heeft Piotr Murach notifications@github.com het volgende geschreven:

I like the word :choice, especially for multiple conditions. Tentatively, I would propose to do

event :next do
choice :company_form => :agreement_form, :if ....
choice :company_form => :promo_form, :if ....
choice :company_form => :official_form, :if ....
default :promo_form
end
The first condition that matches is the transition that is performed. Otherwise the default state is set. This would mean the if/unless can be reused in the conditional pseudo state implementation. Thoughts?


Reply to this email directly or view it on GitHub.

@piotrmurach
Copy link
Owner Author

Well sir you are driving a hard bargain 😄 How about if we do this

event :next, from: :company_form do
  choice to: :agreement_form, :if ....
  choice to: :promo_form, :if ....
  choice to: :official_form, :if ....
  default :promo_form
end

I'm in favour of block as I wounldn't like people using loads of hash options for event specification. I think readability is important and enforcing it through this specific block case would be appropriate?

@kjwierenga
Copy link

I was hoping you would come up with this. This syntax removes the duplication and ambiguity. Nice!

The syntax with :from prohibits the use of :from as a state name just like with normal transitions.

Op 19 mei 2014 om 23:46 heeft Piotr Murach notifications@github.com het volgende geschreven:

Well sir you are driving a hard bargain How about if we do this

event :next, from: :company_form do
choice to: :agreement_form, :if ....
choice to: :promo_form, :if ....
choice to: :official_form, :if ....
default :promo_form
end
I'm in favour of block as I wounldn't like people using loads of hash options for event specification. I think readability is important and enforcing it through this specific block case would be appropriate?


Reply to this email directly or view it on GitHub.

@piotrmurach
Copy link
Owner Author

I've implemented the choice pseudo state with agreed semantics. The added benefit is that you don't have to use the choice DSL, you can resort to using plain events syntax. Thank you for the contribution!

@kjwierenga
Copy link

This worked out nicely. Well done! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants