Google Groups

Re: undo()?


Luke Palmer Jun 29, 2004 4:31 PM
Posted in group: perl.perl6.language
Jonadab the Unsightly One writes:
> Michele Dondi <bla...@pcteor1.mi.infn.it> writes:
>
> > I must say I've still not read all apocalypses, and OTOH I suspect
> > that this could be done more or less easily with a custom function
> > (provided that variables will have a method to keep track of their
> > history, or, more reasonably, will be *allowed* to have it), but I
> > wonder if Perl6 may include a builtin undo() function to recover
> > values prior, say, to the last assignement (or push() or,
> > etc. etc.[*])
>
> Hmmm...
>
> If we have $foo.undo(), then we will want a multi-step undo to go with
> it, probably $foo.undo($n), with $n able to be negative for redo.  Are
> we prepared to give the mouse that cookie?  (This is not intended as a
> rhetorical question; I suspect people will stake out both positions.)
>
> I heard a rumour we were getting continuations (a la Scheme).  They
> wouldn't be tied to a specific variable like what you propose, but
> they would allow the state of the entire process to be rolled back to
> an earlier point, or something along those lines.

Oh no!  Someone doesn't understand continuations!  How could this
happen?!  :-)

You need two things to bring the state of the process back to an earlier
state: undo and continuations.  People say continuations are like time
traveling; I like to put it this way:

Say you're in the kitchen in front of the refrigerator, thinking about a
sandwitch.  You take a continuation right there and stick it in your
pocket.  Then you get some turkey and bread out of the refrigerator and
make yourself a sandwitch, which is now sitting on the counter.  You
invoke the continuation in your pocket, and you find yourself standing
in front of the refrigerator again, thinking about a sandwitch.  But
fortunately, there's a sandwitch on the counter, and all the materials
used to make it are gone.  So you eat it. :-)

A continuation doesn't save data.  It's just a closure that closes over
the execution stack (and any lexicals associated with it; thus the "I
want a sandwitch" thought).  If things change between the taking and
invoking of the continuation, those things remain changed after
invoking.

> You could make the programmer specify which variables he wants delta
> data for, and then any *others* wouldn't keep it and wouldn't be
> undoable.
>
> use undo <<foo bar baz>>; # Or use the funny characters I can't type.
> my $foo++;  $foo.undo();  # Undoes the increment.
> my $quux++; $quux.undo(); # Throws an exception or something.

A much more useful way to do this would be:

    use undo << $foo $bar $baz >>;
    my $foo = 41;
    my $state = undo.save;
    $foo++;  $foo.undo($state);  # or perhaps $state.remember;

That is, you save the state at certain points in execution and remember
them later, rather than quantizing on some arbitrary "step size" (one
instruction).

I don't want to think about what happens when you write:

    use undo << $state >>;
    ...

Luke

> --
> $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
> split//,"ten.thgirb\@badanoj$/ --";$\=$ ;-> ();print$/
>