So, if I understand coroutines correctly, what about the following idea?

Am I missing anything here? This implementation seems a lot simpler (and closer to Perl6 syntax) then the Coro bundle on the CPAN.

As far as I can tell, this would still be a rather limited implementation and might not work with closures. However, it seems so obvious that I know I have to be missing something...

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: Coroutines in Perl 5
by Anonymous Monk on Aug 07, 2002 at 02:24 UTC
    The Coro bundle tries to implement continuations. The function that you are looking at is for co-routines.

    You can implement co-routines in terms of continuations. The reverse is not true. But co-routines are enough for a lot of what you want continuations for in practice.

Re: Coroutines in Perl 5
by RMGir (Prior) on Aug 06, 2002 at 19:28 UTC
    Hmmm, you started my mind down a twisty path filled with things like invoking perl with -P and writing strange macros to do yield.

    I hope I can find my way out without actually DOING any of those evil things! :)
    --
    Mike

Re: Coroutines in Perl 5
by rcaputo (Chaplain) on Aug 14, 2002 at 02:35 UTC

    I suggested something similar to perl5-porters in message <199702071400.JAA00295@anshar.shadow.net>. I was writing a MUD in Perl that needed to multitask programs, and I was considering breaking procedural code into small state machines. This is the sample MUD code I included in the message:

      count = 10000000
      while count--
        say "hello, world!  enter some text: "
        getline some_text
        if some_text eq 'quit'
          last
        endif
      endwhile
      say "\ngoodbye, world!\n"

    The idea was to break it into basic blocks-- chunks of code delimited by branches-- and perform implicit yields at each branch. I intended to implement the I/O functions like say() and getline() so they would suspend MUD tasks until the calls had completed.

    My intention was to "compile" the above MUD code by first translating it into Perl and then using eval() to "assemble" it into bytecode. Here's the Perl sub that the previous code would have been translated into:

      sub aaaaa {
        # assumes the existence of a tasking/event kernel
        my $task = shift;
        my $namespace = $task->{"namespace"};
        my $ip = $task->{'instruction pointer'}; # state
    
        # initial entry point
        if ($ip == 0) {
          $namespace->{'count'} = 10000000 ;
          $task->{'instruction pointer'} = 1;
        }
        # top of while loop
        elsif ($ip == 1) {
          if ($namespace->{'count'}--) {
            $task->say(qq(hello, world!  enter some text: ));
            # soft block on 'getline'
            $task->{'blocking'} = 'getline';
            $task->{'instruction pointer'} = 2;
          }
          else {
            $task->{'instruction pointer'} = 3;
          }
        }
        # "return" from getline
        elsif ($ip == 2) {
          $namespace->{'some_text'} = $task->getline();
          if ( $namespace->{'some_text'} eq q(quit) ) {
            $task->{'instruction pointer'} = 3;
          }
          else {
            $task->{'instruction pointer'} = 1;
          }
        }
        # after endwhile
        elsif ($ip == 3) {
          $task->say( qq(\ngoodbye, world!\n) ) ;
          $task->{'instruction pointer'} = -1; # signals end
        }
      }
    

    I thought this was possible in 1997, and I think it may even be practical now that we can manipulate and generate bytecode directly from Perl programs.

    -- Rocco Caputo / poe.perl.org