All bytes
ProgrammingTuesday, 02 June 2026 · 19:07 EAT

Prefer explicit state machines over boolean flags

When a process has more than two states, boolean flags silently lie about what the system can do.

A boolean flag like `isApproved` looks clean at first, but workflows rarely stay binary. Once you add `isRejected`, `needsReview`, `isEscalated`, the booleans multiply and every combination must be accounted for — including the impossible ones. Invalid states like `isApproved && isRejected` compile happily and crash at runtime.

An explicit state machine with documented transitions (pending → review → approved | rejected) makes invalid states unrepresentable by design. Any code path that violates the transition table either won't compile (with a tagged union) or fails at a clear guard clause, not deep in a tangle of compound conditionals.

The overhead is one enum and one switch. In return you get readable logs, safe refactoring, and a model that both developers and product people can read without translation. When a ticket says 'add cancellation', you add one variant and one transition instead of editing every boolean check in the codebase.

Takeaway

If you need more than one boolean to describe a thing's state, you need a state machine.