Undo and redo require a state model
This lesson uses the behavioral-contracts.zip runtime comparison API.
Its policies differ deliberately from core behavioral-patterns.zip; see the
contract comparison.
What this concept is
A local undo history records committed states or reversible operations. Define the state and observation boundary before choosing Command classes, closures or plain functions. The lab uses immutable text snapshots and a cursor into history.
Why it matters here
Undo correctness depends on failure, no-op and branch behavior, not on whether an object has a method named undo.
Concrete example
Start with empty text, insert A, insert B, undo, then insert C. States are empty, A, AB; undo returns A; the new edit creates AC and discards the former redo branch. Redo now returns false. By contrast, inserting an empty string after undo is a valid no-op: it creates no entry and preserves the redo branch.
Common confusion / misconception
Validation after history mutation can corrupt undo even if the visible text stays unchanged. Restoring a text snapshot cannot unsend an email or reverse an external side effect. Local undo is not a distributed transaction rollback.
How to use it
For insert/delete, validate integer positions (excluding bool), range and string inputs before modifying history. A rejected command preserves text, cursor and redo availability. Deleting zero characters is a no-op. undo/redo return false at the ends without changing state. snapshot returns an immutable tuple (text,cursor,tuple(history)); callers cannot mutate internal history through it. Full snapshots simplify reasoning but retain total text proportional to all history versions.
Check yourself
After insert A, insert B, undo, and an invalid deletion, should redo still restore AB? What about a valid zero-length deletion?
Mini drill or application
Write the state transitions and expected snapshots before coding. Compare full snapshots with inverse edits: inverse edits may save storage but require a proof that every inverse restores the intended state under the same history/ownership assumptions.
Read this only if stuck
Use the existing book/reference map and runtime reading guide. The Design Patterns book index supplies pattern vocabulary; the local lab contract specifies its actual semantics.