--- Michael Lazzaro <[EMAIL PROTECTED]> wrote:
> 
> How, then, would you design an interface around (Concept 1) -- the 
> listener/eventloop/subprocess model?  Pseudocode for a top-level
> event 
> loop might be something like:
> 
>      loop {
>          sleep($fraction), next
>            unless $e = get_event();
> 
>          process_event($e);
>      }
> 

What about this:

1. C<yield> always acts the same way -- stores args in CurThread.result
and gives up control to [?something?].

2. Using the keyword (probably function) C<coro> returns a Code object
that when called executes in serial, in the current thread context, and
causes C<yield> to transfer control back to the caller (essentially
call-cc) returning the result from yield. 

3. Using the keyword (probably keyword - it's complex) C<thread> spins
off another thread of execution, causing yield to block.

4. Using C<resume> DTRT. In order to support arg-resetting, maybe a
simple call does no-arg-reset, while a resume passes new args. Or vice
versa.

E.g.,

sub fibs(?$a = 0, ?$b = 1) {
  loop {
    yield $b;
    ($a, $b) = ($b, $a+$b);
  }
}

print fibs;   # Error: use of yield without thread or coro context.
             
print coro fibs; # Coderefs autoderef into calls, right?

print thread fibs;  # Magic Thread object treats "FETCH" as "wait".


Continuing:

Anyone can yield, so long as there's two active threads. Just one
thread produces an error/warning/exception/whatever.

Anyone can yield if there's a coro entry on the stack someplace.

If there's two active threads and a coro entry, the nearer (most
recently placed on the stack) wins.

There's an optional arg to yield to override this, as with C<leave>. Or
maybe yield is a method on both the Coroutine and Thread classes.
Either way, it can be made explicit.

Recursing doesn't create a new coro unless you say C<coro>.

Saying C<my &left = coro &_;> is how you create a recursive coro.

-4,-2 s/coro/thread/g

Exampling:

sub traverse(Hash $tree) {
  return unless $tree;
 
  traverse $tree{left} if $tree{left};
  yield $tree{node};
  traverse $tree{right} if $tree{right};
}

my %hash is Tree;
my &cotrav := coro &traverse(%hash);
print $_ for <ctrav.resume>;

my &thtrav := thread &traverse(%hash);
print $_ for <thtrav.resume>;


=Austin


Reply via email to