The Circles of Mutable State
Scott Johnson has an excellent comment on the Lambda the Ultimate forums titled “Different levels of mutable state badness”:
The vestuble: Non-mutable state. Just so we have a frame of reference. (Some may argue that this is Heaven rather than the outermost circle of Hell, but in Heaven all the problems are already solved. :) )
1st circle: Mutable state which is not externally observable (given the programming model). Such things as variables cached in registers and other optimizations performed by the machine.
2nd circle: “Monotonic” mutable state. Discussed a bit in CTM, these correspond to variables which can be bound separately from their definition (but once bound cannot be re-bound), lazy evaluation, etc. In general, preserve referential transparency, and are well-behaved.
3rd circle: Linear mutable state. Mutable variables which are accessed from only one place; and generally aren’t subject to aliasing. Examples include local variables in functions (ignoring the issues of lexical closures which might alias such variables, and call-by-reference), “private” variables within objects, etc.
4th circle: Managed mutable state. State in a database or some other system which provides transaction semantics and other means of arbitrating access to the shared variables.
5th circle (getting hotter): Aliased mutable state. Mutable variables/objects which are “used” in numerous different contexts (and therefore aliased)—and thus frequently used as a backdoor communications channel (often unintentionally). Often described as a “feature” of certain OO languages (much the same way pointer arithmetic is trumpted as a feature of C).
6th circle (even hotter): Global (unmanaged) mutable state. As bad as the previous, but as the state is globally exported, you don’t know WHO might be messing with it, or where.
7th and 8th circles: Currently unoccupied, though I await suggestions. :) Feel free to interpose suggestsions above too, and we can demote intervening circles to fill in the gap.
9th circle: Concurrent mutable state. The obnoxious practice of mutating shared state from multiple threads of control, leading into a predictable cycle of race conditions, deadlocks, and other assorted misbehavior from which there is no return. And if a correct solution (for synchronization) is found for a given program, chances are any substantial change to the program will make it incorrect again. But you won’t find it, instead your customer will. Despite that, reams of code (and TONS of middleware) has been written to try and make this tractable. And don’t get me started on a certain programming language which starts with “J” that saw fit to make EVERY object have its very own monitor….