Introspection
.transitions() returns an array of { from, to, event, after? } records that
describes the entire transition table of the machine — useful for graph
generators, diagram renderers, validators, and for testing the machine definition
itself.
The after Ns annotation on a transition records an informative delay in the
after field of the record. The runtime does not advance automatically after
that time; combine with every/after from the concurrency chapter if you want
real-time triggered transitions.
Timed machine with after annotations; inspects the table and filters the "finish" event row.
// Feature: `.transitions()` — list every transition the machine knows
// Syntax: returns an array of records `{ from, to, event, after? }`.
// Useful for tooling: graph generators, diagram renderers, validators.
// When to use: render the machine, generate documentation, diff two
// machine definitions, machine-test the machine.
// `after Ns` annotates a transition with a delay, recorded in the
// table but not enforced by the runtime — feed it to a scheduler if
// you need real time.
machine Timed {
state Idle, Running, Done
initial Idle
Idle -> Running on start after 0s
Running -> Done on finish after 5s
Done -> Idle on reset
}
let t = Timed.new()
t.send("start")
print(t.state)
// expected: Running
t.send("finish")
print(t.state)
// expected: Done
// Inspect the transition table — print only the "finish" row.
let trans = t.transitions()
for row in trans {
if row.event == "finish" {
print(row.event) // expected: finish
print(row.from) // expected: Running
print(row.to) // expected: Done
}
}
Because .transitions() returns plain data — records in an array — you can
iterate, filter, and serialize with any language tool, with no dependency on
special reflection APIs.
See also