
Paul Buchheit: Quick: All actions should have 'undo' - mattjaynes
http://paulbuchheit.blogspot.com/2007/06/quick-all-actions-should-have-undo.html
======
mynameishere
Now if gmail could allow users to undo the "send" action.

I think this is an example of how the experience of gmail can sort-of
trivialize the problems associated with undoing events. How many actions are
there in gmail? Not that many, and it took me 15 seconds of testing to find
this message:

"The contact has been deleted."

Without an undo button (!!!). Undoing is quite a bit more complicated in, say,
a word processor where the different actions are absolutely choked with side
effects. Everything needs to know how to undo itself, hold its state (as well
as application state, where appropriate), sit on a stack waiting for ctrl-Z.
In addition, certain things (like backspacing numerous characters) need to be
able to "fold" together to work correctly. Webapp programmers generally
haven't had to worry about this like desktop programmers...

~~~
nostrademons
Side note: this is one area where functional programming languages can really
shine. In a pure functional language, all data structures are "persistent",
meaning that all previous versions hang around as long as you keep a reference
to them. All you need to do is push them on a stack and you have built-in undo
support for _any_ operation in the language. If functional languages supported
SoftReferences (to my knowledge, none of the pure ones do), you could even
have the garbage collector eat the bottom of the undo stack transparently.

In Haskell you could hide this in a monad: it'd act like the State monad, but
with an additional action to "undo" that just pops the stack and restores the
state. You could also put some special processing in the get/set actions to
handle things like folding transparently.

~~~
weel
In particular, you can hide a bounded stack in a State monad, so you could
prevent the thing from leaking unbounded memory without any garbage collector
magic at all. I guess it would be nice if you could bound the total heap
rather than one particular stack in your program, but I don't think that in
practice that would justify the added complexity in the garbage collector. It
would be interesting, though, and that has been known in the past to be
sufficient reason for people to try and extend Haskell...

