<?xml version="1.0" encoding="windows-1252"?>
<node id="249011" title="Re: (Perl6) Groking Continuations" created="2003-04-08 13:14:29" updated="2005-07-27 15:08:46">
<type id="11">
note</type>
<author id="16591">
andrewc</author>
<data>
<field name="doctext">
&lt;p&gt;Well, I can't claim to great knowledge on this, but I'll give it a go. Schemers out there will probably laugh their heads off.&lt;/p&gt;

&lt;p&gt;Essentially, a continuation is the abstract notion of "what do do next".&lt;/p&gt;

&lt;readmore&gt;
&lt;p&gt;Languages like Scheme carry one of these around on each of their stack frames as something accessible from the language itself. call-with-current-continuation is simply a [Higher Order Function]ish way of doing this.&lt;/p&gt;

&lt;code&gt;
  ;; Guile scheme
  (call-with-current-continuation
     ;; Often abbr'd to call-cc. Takes a function as arg.
     (lambda (fred)
        (+ 3 4)
        (do-something 42 fred)
        (fred 42) ))
&lt;/code&gt;

&lt;p&gt;What's happening here is that when the outer call-cc is run, it takes the continuation of its current context -- where the call-cc would go next if it exited normally -- and 
calls (lambda (fred) ...) with the continuation in the formal parameter 'fred'.&lt;/p&gt;

&lt;p&gt;When the function object in fred is called, the call-cc exits, and the interpreter goes merrily on its way. The call-cc call itself evaluates to whatever is passed to 'fred' when (or if) that gets called.&lt;/p&gt;

&lt;p&gt;Note that the function in 'fred' can be passed around too, and called by other functions. The do-something function used above might decide to call its 'fred' argument with some answer other than 42.&lt;/p&gt;

&lt;/readmore&gt;

&lt;p&gt;You could fake Scheme's call-cc behaviour in Perl using an eval-BLOCK/if($@){} combo. The trick is distinguishing our fake death from a real thrown error:&lt;/p&gt;

&lt;code&gt;
sub call_cc (&amp;)
{
        my $clause = shift;
        my @fake_returns;
        my $fake_continuation;
        $fake_continuation = sub {
                @fake_returns = @_;
                die $fake_continuation;
        };
        eval {
                return $clause-&gt;($fake_continuation);
        };
        if ($@)
        {
                die $@  unless $@ == $fake_continuation;
                return @fake_returns;
        }
        #NOTREACHED
}

print STDERR call_cc {
        my $fred = shift;
        $fred-&gt;(42);
        return 64;  # NOTREACHED
};
print STDERR "\n";
&lt;/code&gt;

&lt;p&gt;But no, it's not a &lt;em&gt;real&lt;/em&gt; continuation.&lt;p&gt;

</field>
<field name="root_node">
248935</field>
<field name="parent_node">
248935</field>
</data>
</node>
