> On Mon, 7 Aug 2000 08:31:24 -0400, John Tobey wrote:
> 
> >A continuation is
> >(abstractly) a copy of the stack.  It's the reverse of eval (or, in C,
> >setjmp) in that it lets you back out of a stack frame and later come
> >back to continue it, possibly many times.
> 
> What's the difference with coroutines?

continuations represent the rest of the program from the viewpoint of a 
single expression -- how the program "continues" once the expresion is 
evaluated.  I'm most familiar with continuations from scheme, where 
they are captured by the form (call-with-current-continuation foo), 
which passes foo the current continuation as a function that takes one 
argument.

In perl, (assuming that callcc(&) was a function that did the same 
thing), you could use it to do things like:

sub tsearch {
  my ($t,$p,$continuation) = @_;
  &$continuation($t) if $t->data ~= /$p/;
  tsearch($t->left,$p,$continuation);
  tsearch($t->right,$p,$continuation);
  return undef;
}

$matched_root = callcc( sub {tsearch($tree,$pattern,$_[0])});

This will search $tree for a node who's data matches $pattern, and 
return the result to $matched_root.  If no node matches, it returns 
undef.  When a match is found, it returns -immediately-, and does 
return through possibly multiple nested invocations of tsearch.

tsearch could be written without continuations and shortcircuiting the 
search as:

sub tsearch {
  my ($t,$p) = @_;
  return $t if $t->data ~= /$p/;
  my $l = tsearch($t->left,$p);
  return $l if $l;
  my $r = tsearch($t->right,$p);
  return $r if $r;
  return undef;
}

But this has to do lots of checking of "if $l" and "if $r" in a deeply 
nested case.

The "back out of a stack frame and later come back to continue it" bit 
is since continuations are first-class values, they can be stored.  But 
remember:  They represent the -entire- future history of the program.  
That means that:

our $cont;
sub storeit {
  ($cont) = @_;
  return 0;
}
$bar = 'a';
$num = callcc(\&storeit);
print "$num$bar";
$bar++;
&$cont($num+1) if $num<10;

will print "0a1a2a3a4a5a6a7a8a9a" (and not "0a1b2c3d4e5f6g7h9i" as you 
might think).  At the time the continuation is saved, $bar was 'a'.  
(Note:  I'm not entirely certain about that...  It might print 
0a1b...). This is the point where people can freak out about the 
effects of continuations.  Being able to save the "rest of the program" 
into a variable is not something most people consider.

Continuations can be used to implement co-routines:

sub cofoo {
  my ($arg,$co) = @_;
  while ($arg < 10) {
    print "f$arg";
    $arg = callcc(sub { &$co($arg+1,$_[0];});
  }
  100;
}

sub cobar {
  my ($arg,$co) = @_;
  while ($arg < 10) {
    print "b$arg";
    $arg = callcc(sub { &$co($arg+1,$_[0];});
  }
  200;
}

print &cofoo(1,\&cobar);

will print:

f1b2f3b4f5b6f7b8f9100


Is this clear?

> 
> -- 
>       Bart.

-- 
     Buddha Buck                             [EMAIL PROTECTED]
"Just as the strength of the Internet is chaos, so the strength of our
liberty depends upon the chaos and cacophony of the unfettered speech
the First Amendment protects."  -- A.L.A. v. U.S. Dept. of Justice


Reply via email to