Skip to content

Instantly share code, notes, and snippets.

@mogsie
Created January 12, 2018 11:33
Show Gist options
  • Save mogsie/529de70de9e36776e97cd56296798fb1 to your computer and use it in GitHub Desktop.
Save mogsie/529de70de9e36776e97cd56296798fb1 to your computer and use it in GitHub Desktop.

I'm wondering if it would be useful to provide a way to have guards be kept out of the state machine, to keep it all "pure function".

The way I thought it might work would be to add a parameter to the transition to specify the value of any guards. The guards would always be optional, but would of course influence the outcome. Here's a machine with a named guard (I use 'guard' instead of 'cond' because I like statechart terminology better than scxml):

m = Machine({
  foo: {
    on: {
      A: bar,
      B: {
        target: bar
        guard: isEmpty
      }
    }
  },
  bar: {}
})

var object = []

direct = transition(m.initialState, 'A');  // transitions directly to bar, as before
guarded = transition(m.initialState, 'A');  // about to transition from foo to bar, but it was guarded.
guarded.missingGuards; // [ "isEmpty" ]
failure = transition(m.initialState, 'A', { isEmpty: false }); // state is still "foo" — the event was basically not handled.
success = transition(m.initialState, 'A', { isEmpty: true }); // state is "bar" as the guard allowed the transition to happen.

A successful state transition requires that you verify that missingGuards is empty. If there are any missingGuards then you need to retry the state transition providing those missing guards. The missingGuards would be a property on the State object returned.

The third parameter to transition would be somewhat of a bitset with the names of the guards and their boolean values.

The guard attribute should allow boolean logic, though, so that it's possible to say guard: "!isEmpty && ready" in the machine definition, and that this would require the isEmpty and ready guards to be provided.

@mogsie
Copy link
Author

mogsie commented Jan 13, 2018

Well, order does matter, and I feel that's a rather contrived example.

It's a bit like saying that boolean logic i flawed because you might write stupid stuff like if (isEmpty && somethingElse && isEmpty) — Yes, the last isEmpty is redundant :).

These guards are the if tests of statecharts, and we should spend time getting them right, that's for sure :)

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