Are there any GUI systems that have undo/redo bake...
# thinking-together
Are there any GUI systems that have undo/redo baked into the semantics? Meaning a framework where you as the programmer define an action in a way that’s invertible by construction, and then the system can automatically build an undo/redo framework around your actions.
It's very early, but I'm working on one. All actions have reverse-actions, that return reverse-reverse-actions, while invocations build a tree structure/ history, thus allowing you to go back n fourth and around how much you want. You may also "group"/nest actions such that the undo granularity may be controlled.
👋🏿 2
(this also found the basis for the version control + collab functionality)
Anything specific you're thinking about?
Does the programmer have to separately specify how actions work from reverse-actions, or can the reverse-action be derived from the action?
Auto derived if building logic from existing actions w reverse functionality. When interacting with external services, eg. sending an sms, that action might not be easily undoed.
Sounds cool! Would love to see a prototype when you have one. I guess I’m thinking about this from the perspective of ML, where auto-differentiation has made a world of different in creating new models. It seems like a similar kind of program analysis could be super useful in easily creating direct manipulation interfaces with essential functionality like undo/redo.
❤️ 2
It makes sense that, for an arbitrary action defined in e.g. Python, there’s no obvious way to invert it. The autodiff folk get away with it because their basic operators are all high school calculus.
This used to be a common feature of GUI frameworks, years ago when I last worked with them. You use the Command design pattern, each command has an
method, the undo stack is a stack of Command objects.
I just checked Qt, and it has an undo framework based on the Command pattern.
Or... maybe a Command object is not what you meant by "invertible by construction".
Undo/Redo is a fascinating subject. In Adobe Photoshop, they use the ability to undo actions stored in the history palette to great effect, and it is linked with their actions palette, which permits automation to a pretty high degree. however, their undo/redo doesn't affect the user interface, so when you undo a series of actions, you might have to undo whatever changes to the interface were done. In my kids program Flying Colors (available for free download at, took reversibility all they way into interface, so that when you undo it also undoes the user interface. This also generated the possibility of having the software self-operate. A few products, very few, can do self-operation, and if you add audio narration, bingo you have a great lesson system. In my case it was about training young people to do bitmap painting. Having products self-operate is a wonderful training method, and the kind of ghost mode where there is an unseen hand moving the cursor and clicking is a fabulous way to teach. It was incredibly difficult to do though, and i haven't done it since. One area where i have continued research is in the issue of duplicating a customer problem in the lab. So often in web apps and interactive graphic software the customers hit a problem, report it, and because it can't be duplicated, it never gets fixed. So this is the problem i am solving in my Beads system, where i record the history, and the users can send that history and replay the bug at the factory. Not easy to to do actually, which is why you don't see it hardly at all.
❤️ 3
One other consideration - having implemented undo/redo in the past is - sometimes individual "actions" shouldn't be "undoable" rather a batch of operations should be undoable. So simply recording individual operations and describing the reverse operation isn't enough. You end up needing to describe "undo points" to fast forward the operation. This is most obviously implemented in text editors. Try writing some words and hitting undo in slack 🙂. Definitely not an insurmountable problem, but just another thing that makes undo/redo interesting to automate in the general case.
@Parris Oh yes! There is a lot you could want from a history system, some notes: - undo/data + actions history tree - separate "channels" (eg. UI, document data, analytics data) // eg. undoing should sometimes undo document data change, but not UI, sometimes both, etc - nested grouping (eg. "drawing a line" is ("pen down", "pen move", "pen up")) - possible to undo full "draw square", or just undo last "side", or even just last "pen up" and "pen move". - reverse-reverse to allow reverse of one specific action after other actions performed (eg. not "undo last delete", nor "undo delete of XXX when it happened", but "undo delete of XXX now") - all three variants should be possible? - in extension, this "history tree" could be shared across clients, and thus form a basis for both the collab and version control functionality, as well as time-travel debugging and full replay (as in Edwards system above)
I'm not sure you'd want to emulate it, but vim has a very interesting undo/redo model.
I just do a simple history[] stack of diffs and then "undo" just iterates through the stack applying each diff stopping at the desired step...Then you just need to call "save()" after each change operation and append to that stack
Good point @Parris how the undo command often groups multiple actions together. Text editors are also complicated by per file undo stacks coupled with cross file operations like find and replace.