Continuation-passing style in Perl 5

While I was thinking about my latest perl module, a logic programming framework, I realized that it would be really nice to have continuations. So after going through all the contortions of getting around that limitation using closures, I discovered that it’s possible to use continuation-passing style in Perl:

sub fibo {
    my ($x, $c) = @_; sub {
    if ($x < 2) { sub {
        $c->(1);
    }}
    else { sub {
        fibo($x-1, sub {
        my $f1 = $_[0];
        fibo($x-2, sub {
        my $f2 = $_[0]; sub {
        $c->($f1 + $f2);
    }})})}}}
}

my $next = fibo(10, sub { print "$_[0]\n"; exit });

# kernel
$next = $next->() while 1;

Don’t you just dream of programming like that? It’s scary how reminiscent of LISP that is… (Note that the big slew of braces at the end of fibo() has two closing parentheses in it). If you’re having trouble reading that, you’re not alone. But the basic idea is that each time you call a routine, it does something and then returns what it should do next. You can’t use traditional control structures like while() with this style, but you can get the same behavior by passing continuations around.

About these ads

4 thoughts on “Continuation-passing style in Perl 5

  1. That’s nasty. As someone who was programming with continuations in Common Lisp earlier today, I have to say that it looks completely unlike Lisp. In Lisp, you see, we use the great benefit of all those parentheses: source-code transformations work. Including CPS transforms. ;-)

    And your indentation is confusing. That said, this is cool stuff. Quite mind-bending, and it’s nice to see that closures are coming into more common use.

  2. Yeah, I’ll admit that it’s almost, but not quite, entirely unlike lisp. My indentation just reflects what the code would look like without all the closures sitting there. I’ve just defined my semicolon to be sub {. I’ll be so happy when I rewrite my Logic module in Perl 6, which does have continuations. No more awkward callbacks and stack management!

  3. Do you know if this kind of technique could be used to support continuation-based Web programming?

  4. Probably not. Continuation-based web programming requires *serialized* continuations. While you can take a continuation using this style, you’d need some way to put that into a file. And I don’t know of any module that will serialize two closures correctly if they close over the same thing. Also, without a very complicated source filter over the top of this, the awkward style of programming would probably outweigh the benefits of using it in the first place.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s