# Erlang Authors - gen_statem Behaviour (Highlights)

## Metadata
**Review**:: [readwise.io](https://readwise.io/bookreview/57097277)
**Source**:: #from/readwise #from/reader
**Zettel**:: #zettel/fleeting
**Status**:: #x
**Authors**:: [[Erlang Authors]]
**Full Title**:: gen_statem Behaviour
**Category**:: #articles #readwise/articles
**Category Icon**:: 📰
**URL**:: [www.erlang.org](https://www.erlang.org/doc/system/statem)
**Host**:: [[www.erlang.org]]
**Highlighted**:: [[2025-12-26]]
**Created**:: [[2025-12-27]]
## Highlights
- State(S) x Event(E) -> Actions(A), State(S') ([View Highlight](https://read.readwise.io/read/01kddfkjjv02vffdjq0jqvyvb3)) ^970030582
- In `gen_statem` we define a *state change* as a *state transition* in which the new state `S'` is different from the current state `S`, where "different" means Erlang's strict inequality: `=/=` also known as "does not match". ([View Highlight](https://read.readwise.io/read/01kddfn5d2cqqqfc66302zpwqk)) ^970030766
- [*State Enter Calls*](https://www.erlang.org/doc/system/statem/#state-enter-calls) (see that section) are also handled by the event handler and have slightly different arguments. ([View Highlight](https://read.readwise.io/read/01kddgpraz8dawsak22rfm0s69)) ^970036457
- **`{next_state, NextState, NewData [, Actions]}`** Set next state and update the server data. If the `Actions` field is used, execute [*Transition Actions*](https://www.erlang.org/doc/system/statem/#transition-actions) (see that section). An empty `Actions` list is equivalent to not returning the field. ([View Highlight](https://read.readwise.io/read/01kddgqw85akg8efe38wh7xe1k)) ^970036504
- If `NextState =/= State` it's a *state change* and `gen_statem` does some extra things: the event queue is restarted from the oldest [postponed event](https://www.erlang.org/doc/system/statem/#postponing-events), any current [*state time-out*](https://www.erlang.org/doc/system/statem/#state-time-outs) is canceled, and a [*state enter call*](https://www.erlang.org/doc/system/statem/#state-enter-calls) is performed, if enabled. The current `State` becomes `OldState` in a *state enter call*. ([View Highlight](https://read.readwise.io/read/01kddgs8fry643084sknkbvkc1)) ^970036576
- Same as the `keep_state` or `keep_state_and_data` values, but if [*state enter calls*](https://www.erlang.org/doc/system/statem/#state-enter-calls) are enabled; repeat it as if this state was entered again. In this case `State` and `OldState` becomes equal in the repeated *state enter call* since the state is re-entered from itself. ([View Highlight](https://read.readwise.io/read/01kddgtq5fkzwwn2r62dd9cwg5)) ^970036640
- The `gen_statem` behaviour can, if this is enabled, regardless of *callback mode*, automatically call the [*state callback*](https://www.erlang.org/doc/apps/stdlib/gen_statem#t:state_enter/0) with special arguments whenever the state changes, so you can write state enter actions near the rest of the *state transition* rules. ([View Highlight](https://read.readwise.io/read/01kddhdvgnrntmt9ahaw996s4h)) ^970039462
- Since the *state enter call* is not an event there are restrictions on the allowed return value and state [*transition actions*](https://www.erlang.org/doc/system/statem/#transition-actions). You must not change the state, [postpone](https://www.erlang.org/doc/system/statem/#postponing-events) this non-event, [insert any events](https://www.erlang.org/doc/system/statem/#inserted-events), or change the [*callback module*](https://www.erlang.org/doc/system/statem/#callback-module). ([View Highlight](https://read.readwise.io/read/01kddhgthasq4vv7vks5t4h0gq)) ^970039883
- The first state that is entered after [`gen_statem:init/1`](https://www.erlang.org/doc/apps/stdlib/gen_statem#c:init/1) will get a *state enter call* with `OldState` equal to the current state. ([View Highlight](https://read.readwise.io/read/01kddhhda4pwtszghftw96w0z4)) ^970039915
- **[`state_timeout`](https://www.erlang.org/doc/apps/stdlib/gen_statem#t:state_timeout/0)** - There is one [*state time-out*](https://www.erlang.org/doc/system/statem/#state-time-outs) that is automatically canceled by a *state change*. ([View Highlight](https://read.readwise.io/read/01kddhm4edc4nzexnceyqyvcp4)) ^970040314
- **[`timeout`](https://www.erlang.org/doc/apps/stdlib/gen_statem#t:event_timeout/0)** - There is one [*event time-out*](https://www.erlang.org/doc/system/statem/#event-time-outs) that is automatically canceled by any event. Note that [postponed](https://www.erlang.org/doc/system/statem/#postponing-events) and [inserted](https://www.erlang.org/doc/system/statem/#inserted-events) events cancel this time-out just as external events do. ([View Highlight](https://read.readwise.io/read/01kddhm11bap7xfr8y1ybvetjx)) ^970040244
- Sometimes events can arrive in any state of the `gen_statem`. It is convenient to handle these in a common state handler function that all state functions call for events not specific to the state. ([View Highlight](https://read.readwise.io/read/01kddj1584s1p750xmqe71z7xq)) ^970043256
- If you want to ignore a particular event in the current state and handle it in a future state, you can postpone the event. A postponed event is retried after a *state change*, that is, `OldState =/= NewState`. ([View Highlight](https://read.readwise.io/read/01kddj7bbpybqnjntxswd397jq)) ^970043797
- You can generate events of any existing [type](https://www.erlang.org/doc/apps/stdlib/gen_statem#t:action/0), but the`internal` type can only be generated through action `next_event`. ([View Highlight](https://read.readwise.io/read/01kddjfsgm65q5p0x6d5vg9bxp)) ^970044451