soma.cell

State machines

State machines, in the reference of the Soma programming language (soma 3.2.4). A block marked ✓ is a whole program that soma check accepts; the others are excerpts.

state order {
    initial: pending
    pending -> validated { guard { amount > 0 } }
    validated -> sent
    sent -> filled
    sent -> rejected
    filled -> settled
    * -> cancelled           // from any state
}

// In handlers:
transition("order_id", "validated")    // move state (from wherever the instance is)
transition("order_id", "pending", "validated")  // …declaring the source: `soma check`
                                       // verifies the edge pending -> validated exists, and the
                                       // call raises invalid_transition when the instance is
                                       // anywhere else — verify then sees which edge the handler takes
let status = get_status("order_id")    // current state
let valid = valid_transitions("order_id") // available transitions

// A guard reads the locals of the handler that calls transition(). It is
// PROVEN by `soma verify` when every such handler narrows the guard's
// variables with a `require` (or an enclosing `if`) before the call and does
// not reassign them in between; otherwise it is reported ⚠ runtime-checked
// (and `verify --strict` fails on it):
//   pending -> validated { guard { amount > 0 && amount < 1000 } }
//   on validate(id: String, amount: Int) {
//       require amount > 0 && amount <= 999 else BadAmount   // proves the guard
//       transition(id, "pending", "validated")
//   }