[erlang-questions] gen_statem state enter call and changing t oanother state

Fred Hebert mononcqc@REDACTED
Mon Jun 11 18:55:40 CEST 2018

On 06/11, Raimo Niskanen wrote:
>The feature you ask for probably makes more sense for
>But there are still some hairy semantics to get right:
>* If changing states in state_enter call hops more than once - what should
>  OldState be after the first state_enter call?  I.e how much of a state
>  change should changing states in the state_enter call be regarded as.
>  As the gen_statem code looks now it seems to be easier to retain
>  the original OldState and not regard the state change as complete until
>  the final state of the state change has been deduced.
>* If changing states back to the OldState - should postponed events be
>  retried?  I think not - you in effect stayed in the same state.
>* Same again: if changing states back to the OldState - should the state
>  enter call of the OldState be re-run or not?  As the gen_statem code
>  looks now it seems to be hard to see this as anything else than staying
>  in the same state hence not running the state_enter call.
>  Is that intuitive?
>* Should we also allow {next_event,...} from a state_enter call?
>* There might be more...

- Would the state enter represent having entered the state or entering 
  the state as soon as the callback returns?
  If it represents having entered the state:
    - postponing would conceptually make sense, even if it won't in 
      practice (because you may just forever get back to the postponing 
    - trace/debug calls need to show the state transition as having 
      happened with no actual events being generated (or rather event a 
      caused state to change to A, and then state changes B and C 
      happened with no prompting) -- otherwise you need to consider 
      state enter events the same way they'd be with external events and 
      that's even conceptually worse
    - state timeouts are not ambiguous
    - if the events entered the state, it does solve the 'OldState' 
  If it does not represent having entered the state
    - postponing would not conceptually make sense, and won't happen
    - no hard questions about whether enter state events are special 
      events or not
    - state timeouts should possibly not be reset since you have never 
      left the original state until at the end of evaluating the 'enter' 
      chain of events
    - this ends up having the possibility to have a repeated 'OldState' 
      value, which currently clashes with the expectation that the first 
      enter event of a FSM is a duplicated one. This would make any 
      double-transition look like the first transition of the process's 

It seems that either way, there is a conceptual confusion as soon as an 
enter state event is allowed to force a change to a new state. I'd 
rather see the possibility forbidden.

As for allowing next_event in an enter event, I'm not a fan. If you 
really need an event to run as the first thing in an enter event, just 
run it in the enter event itself? Otherwise this lets you conceptually 
do the same thing as multiple enter-state events with a state transition 
it seems.

>I think the semantics is hairy enough already, so I still have a bad
>feeling about this...  But I have asked some colleauages to also
>contemplate it, we'll see if they can find the time since we are in
>the middle of the 21.0 release circus.

Yes. One of the main complaints of gen_statem is that it is a complex 
behaviour and people take a long while to get adapted. It could be 
argued that the separation between enter and normal events is already 
part of that complexity, but in my opinion, not putting these barriers 
in place actually increase the overall potential system complexity even 

I still think gen_statem should have been simpler than it is today, so 
I'll be vocal about preventing further complexity from being added to 

>The only thing that _has_ to be prohibited from a state_enter call is
>'postpone' since there is no event to postpone.
>The only reason I have for prohibiting state change and event insertion
>from state_enter calls is that I am afraid they would get too hairy semantics
>and hence cause too hard to understand state machines.

Yes, that is an entirely valid concern. I think it is worth making the 
existing typespecs a tad more complex to prevent user code from being 
even worse than that.

Currently the typespecs are too obtuse to be good docs on their own 
(while they're kind of okay for supervisors and gen_servers), but they 
represent an intrinsinct complexity warning that a tutorial would have 
to alert the user to anyway if they were to be simplified. Might as well 
keep the type complexity and just have the tutorial fix things right 

I'm opposed to adding more conceptual complexity to gen_statem.


More information about the erlang-questions mailing list