As developers, we are all familiar with step by step debugging.
That little 'step' button gets a lot of use.
It often goes like this:
Step.
Oh, that's unexpected.
How on earth did we get here?
Let's reload.
Step.
Darn, I missed it.
Restart.
Step.
Wouldn't it be great if one could step backwards?
Stepping backwards is like putting the toothpaste back into the tube.
It's easy if you know how.
Like any good debugger, the JS-Interpreter allows one to execute one step at a time.
Step.
But of course there's no way to undo a step.
Separately, the JS-Interpreter also allows one to serialize the state of execution at
any given time.
This writes out not only the current variables, but also the execution pointer, and the entire
JavaScript runtime.
So stepping backwards is conceptually quite simple.
Just serialize the runtime at every step, and push the serialization onto a stack.
When stepping backwards, pop the most recent serialization and load the interpreter with
that state.
One problem is that the serialization is rather large.
Let's measure it.
Yikes.
That's about 300 KB.
Each!
Thus you'll start eating memory faster than you can pop RAM cards into your computer.
The good news is that each serializations doesn't differ much from the next serialisation.
So all we need to do is store the diffs on our stack.
This page implements a fast diff algorithm written in JavaScript.
We'll copy one serialization to the first textarea.
Then we'll step a couple of times, and copy the next serialization to the second textarea.
The result shows that the two serializations are mostly identical, with only a tiny delta
between them.
Putting it all together, one can now step forwards and backwards.
Memory usage is minimal.
Here's a live demo of forwards and backwards stepping using Blockly.
The ability to debug both forwards and backwards offers some interesting possibilities in educational
applications.
If you implement it, we'd really like to hear from you.