15 · every effect, its inverse
Revertible effects
If every change comes with instructions for undoing it, removing a piece stops being a problem.
The central idea is simple to state. Every modification of the environment travels paired with its inverse operation, and the system stores it.
Loading a piece means applying a sequence of changes and stacking their inverses. Unloading it means applying that stack. Nothing more.
An effect and its inverse
And there is an ergonomic detail the paper underlines: the programmer only writes the inverse of each small operation. The inverse of the whole is derived by the system.
The easy case and the real one
Undoing in the reverse order of application always works and requires no condition. Each inverse meets exactly the state its own application produced.
The problem is that real systems do not undo in that order. You remove a piece from the middle while the others keep running. Or several pieces have been interleaving their changes and now the inverses of one are separated by the changes of another.
In those cases, the inverse meets a state that others have moved. And that is where a condition is needed.
The condition
The paper calls it independence, and it has two parts.
- First part They commute The operations of one piece and those of another give the same result in any order.
- Second part They do not disturb each other inverses Neither of them alters the inverse the other produces. Almost every summary omits this half.
When that holds for every pair, you get the result everything else rests on: you can undo in any order and the system returns to its initial state.
A registry of event subscribers meets the condition: two registrations give the same result in either order. An ordered chain of filters does not.
A note of honesty
The paper admits that talking about returning to the initial state is an idealisation, because the physical state is not recovered as such.
Freeing memory returns a block, but does not restore how memory was laid out before it was requested. A generated identifier does not come back by discarding it, because the next creation takes a new one.
That is why all the equalities are read in terms of what an observer can distinguish. And reading it that way is not lowering the bar: it is what makes the result reachable, because two operations can leave indistinguishable states and count as equivalent.