Skip to content

State names

Leon Starr edited this page Aug 4, 2026 · 2 revisions

A state block opens with the unindented state keyword and the state's name:

state HOLDING OPEN

The grammar for the whole header line is:

state_header = "state" SP state_name signature? (SP DELETION)? EOL*
state_name = name

The name is an ordinary name (see Names and delimiters), so it's one or more words joined by single spaces or underscores, optionally ending in a ?. What follows it — a signature (see Signatures) and a deletion marker (see Deletion states) — is optional, giving four possible shapes for the line:

state HOLDING OPEN
state Delete !*
state Request redirect( new dest: Level Name )
state Terminating( reason: Fault Code ) !*

The all-caps convention

You'll notice two visibly different naming styles in the elevator models:

state OPEN
state Cancel open delay

This is a convention, not a grammar rule — the parser is perfectly happy either way. All caps marks a waiting state, where the instance sits doing nothing until an event arrives. Mixed case marks a transient state, one the instance passes straight through while its activity runs.

I find this pays for itself the moment a state model gets big enough to be hard to read. Scanning the Door lifecycle, OPENING, OPEN, HOLDING OPEN, CLOSING, CLOSED and LOCKED are where a door actually rests, while Cancel open delay and Count block are bookkeeping the door does on the way somewhere else.

Name a waiting state for the condition the instance is in, and a transient state for the work it is doing.

Names ending in a question mark

The trailing ? allowed by the name rule is handy for states that exist to make a decision:

state Are we already there?

That's a real state from the Cabin lifecycle. Remember that the ? is part of the name, so every transition targeting that state must include it.

What the parser gives you

The name lands in the name field of the StateSpec_a named tuple, inside the state field of the enclosing StateBlock_a.

Clone this wiki locally