Software transactional memory (STM) manages concurrent mutable state by allowing changes only inside isolated transactions. Separate threads can safely update independent parts of a domain model; when they collide, STM resolves access predictably through waiting, retrying, or rollback rather than hand-built locking protocols. section 9.2 section 7.2.4
The practical design split is simple: build a concurrent domain model from transactional variables and structures, then write transaction functions that modify it. Run those functions atomically in the threaded environment. This separates state representation from behavior while retaining thread-safety. section 9.2.1
STM is most useful when coordination spans more than one shared value:
- Use TVars as fundamental transactional variables; build structures such as FIFO queues from them when the domain needs them. section 9.2.1
- Compose small STM actions into one larger transaction, so related updates are evaluated as a single coordinated operation. section 9.2.1
- Use retry to block a transaction until observed state changes make progress possible, rather than repeatedly polling a resource. section 9.2.2
- Prefer STM when an MVar-based model becomes large or awkward; manually paired acquire-and-release operations are easy to get wrong. section 8.3 section 9.2.2
Bounded process counter
A runtime can keep its current process count in a TVar. The increment transaction reads the count, calls retry at the configured limit, and otherwise writes the incremented value. A decrement transaction simply updates the TVar. Executing each with atomically yields sequential-looking resource control without manual polling or race-prone coordination. section 9.2.2
Figure 9.9 Data model and behavior model in STM
This diagram clarifies the central STM separation: transactional structures form the data model, while transactions form the behavior model executed against it. section 9.2.1
STM can also sit behind an application interface. A reporting channel, for example, can change from an IORef to a TVar, with its update expressed as STM and lifted into business logic through an atomic interpreter. Direct raw mutable references shared across threads are unsafe; deeper state abstraction may be needed when variables must be inspected, limited, persisted, or restored. section 9.2.3
