Larry wrote:
So you can do it any of these ways:
for <$dance> {
for $dance.each {
for each $dance: {
^ note colon
Then there's this approach to auto-iteration:
my @dance := Iterator.new(@squares);
for @dance {
Okay, so now I need to make sense of the semantics of <...> and
C<for> and coroutines and their combined use.
Is the following correct?
==============================================================================
The presence of a C<yield> automatically makes a subroutine a coroutine:
sub fibs {
my ($a, $b) = (0, 1);
loop {
yield $b;
($a, $b) = ($b, $a+$b);
}
}
Calling such a coroutine returns an Iterator object with (at least)
the following methods:
next() # resumes coroutine body until next C<yield>
next(PARAM_LIST) # resumes coroutine body until next C<yield>,
# rebinding params to the args passed to C<next>.
# PARAM_LIST is the same as the parameter list
# of the coroutine that created the Iterator
each() # returns a lazy array, each element of which
# is computed on demand by the appropriate
# number of resumptions of the coroutine body
In a scalar context:
<$fh> # Calls $fh.readline (or maybe that's $fh.next???>
<$iter> # Calls $iter.next
fibs() # Returns iterator object
<fibs()> # Returns iterator object and calls that
# object's C<next> method (see note below)
In a list context:
<$fh> # Calls $fh.each
<$iter> # Calls $iter.each
fibs() # Returns iterator object
<fibs()> # Returns iterator object and calls object's C<each>
So then:
for <$fh> {...} # Build and then iterate a lazy array (the elements
# of which call back to the filehandle's input
# retrieval coroutine)
for <$iter> {...} # Build and then iterate a lazy array (the elements
# of which call back to the iterator's coroutine)
for fibs() {...} # Loop once, setting $_ to the iterator object
# that was returned by C<fibs>
for <fibs()> {...} # Build and then iterate a lazy array (the elements
# of which call back to the coroutine of the
# iterator returned by C<fibs>
==============================================================================
Note: this all hangs together *very* nicely, except when someone writes:
loop {
my $nextfib = <fibs()>;
...
}
In which case $nextfib is perennially 1, since every call to C<fibs>
returns a new Iterator object.
The solution is very simple, of course:
my $nextfib = <my $iter//=fibs()>;
but we might want to contemplate issuing a warning when someone calls
an argumentless coroutine within a scalar context <...>.
Damian