Of course, apart from the "call-with-new-args" behaviour, having Pythonic coroutines isn't noticably less powerful. Given:
sub fibs ($a = 0 is copy, $b = 1 is copy) { loop { yield $b; ($a, $b) = ($b, $a+b); } } we still have implicit iteration: for fibs() { print "Now $_ rabbits\n"; } and explicit iteration: my $iter = fibs(); while <$iter> { print "Now $_ rabbits\n"; } and explicit multiple iteration: my $rabbits = fibs(3,5); my $foxes = fibs(0,1); loop { my $r = <$rabbits>; my $f = <$foxes>; print "Now $r rabbits and $f foxes\n"; } and even explicitly OO iteration: my $iter = fibs(); while $iter.next { print "Now $_ rabbits\n"; } And there's no reason that a coroutine couldn't produce an iterator object with *two* (overloaded) C<next> methods, one of which took no arguments (as in the above examples), and one of which had the same parameter list as the coroutine, and which rebound the original parameters on the next iteration. For example, instead of the semantics I proposed previously: # Old proposal... sub pick_no_repeats (*@from_list) { my $seen; while (pop @from_list) { next when $seen; @from_list := yield $_; $seen |= $_; } } # and later: while pick_no_repeats( @values ) { push @values, some_calc($_); } we could just write: # New proposal sub pick_no_repeats (*@from_list) { my $seen; while (pop @from_list) { next when $seen; yield $_; $seen |= $_; } } # and later: my $pick = pick_no_repeats( @values ); while $pick.next(@values) { push @values, some_calc($_); } These semantics also rather neatly solve the problem of whether or not to re-evaluate/re-bind the parameters each time a coroutine is resumed. The rule becomes simple: if the iterator's C<next> method is invoked without arguments, use the old parameters; if it's invoked with arguments, rebind the parameters. And the use of the <$foo> operator to mean $foo.next cleans up teh syntax nicely. I must say I rather like this formulation. :-) Damian