Exercise 3: Why Macro Undo Order Matters But Iterator Creation Order Doesn't — Possible Solution ==================================================================== WHY MACROCOMMAND'S REVERSED UNDO IS A CORRECTNESS REQUIREMENT ------------------------------ This chapter's own MacroCommand.undo() reverses the order its sub-commands were originally executed in - and this chapter's verified example showed why that matters: undoing turns something OFF that was just turned ON, or back ON if it was turned OFF. If a later command in the macro depends on an earlier one's effect already being in place (for example, a "close the garage" command genuinely needing "stop the car's ignition" to have already executed first), undoing in the SAME order instead of reversed could leave the system in a state that never actually existed during forward execution - a partially-undone, inconsistent middle state. Reversing the order guarantees that undo always retraces the exact same sequence of states the macro passed through going forward, just backward - the only way to guarantee a fully consistent rollback regardless of whether any sub-commands happen to depend on each other. That's a REQUIREMENT, not a convenience - a macro that undid in forward order could produce wrong results for macros whose commands do depend on ordering, even if this chapter's own two-light-and-fan example didn't happen to expose that dependency. WHY TWO ITERATOR OBJECTS' CREATION ORDER DOESN'T MATTER AT ALL ------------------------------ This chapter verified it2 was created AFTER it1 had already been advanced twice - and it2 still started fresh from 'Book A', completely unaffected by whatever it1 had already consumed. That's because each iterator holds its OWN independent _index; neither iterator reads or writes any shared, order-dependent state on the shelf itself. Creating it2 before or after advancing it1 makes no observable difference whatsoever - swap the two lines in this chapter's own verification code and the exact same output would come back. There is no "order of creation" for iterators to get right, because the whole point of Iterator's own design is that each iterator's position is private to itself. THE UNDERLYING REASON FOR THE DIFFERENCE ------------------------------ MacroCommand's sub-commands can have real side effects that interact with shared, mutable state (the actual light and fan devices) - order determines what state exists at each step, so reversing it on the way back out is what keeps forward and backward execution consistent. Iterators, by contrast, are read-only observers with entirely private, independent state (their own _index) - two iterators over the same shelf don't interact with each other at all, so there's no shared state for their relative creation order to possibly affect. WHY THIS WORKS AS AN ANSWER ------------------------------ The answer traces MacroCommand's reversed-undo requirement to a concrete correctness argument (retracing the same states backward, which matters whenever sub-commands could depend on each other) rather than only citing this chapter's own example, and it explains why iterator creation order is provably irrelevant by pointing at each iterator's own private, non-shared _index rather than merely asserting "it doesn't matter."