soma.cell

Transition guards see the calling handler's locals

Pitfall 22 of writing Soma, the programming language: a habit from another language, or a rule that surprises, with what the Soma compiler answers and the form to write.

state expense { initial: approved   approved -> paid { guard { amount < 10000 } } }
on pay(id: String) {
    let amount = amounts.get(id) ?? 0      // the guard reads THIS `amount`
    transition(id, "paid")                 // raises "guard failed…" when false
}

A guard sees: the locals of the handler calling transition(), the cell's memory slots, _id, _from, _to. soma check rejects a guard that reads a name its calling handler never binds. Guards are enforced at runtime; the model checker keeps the edge (an over-approximation, so safety results hold).