> Larry wrote:
>
> So you can do it any of these ways:
>
> for <$dance> {
>
> for $dance.each {
>
> for each $dance: {
> ^ note colon
1- Why is the colon there? Is this some sub-tile syntactical new-ance
that I missed in a prior message, or a new thing?
2- Why is the colon necessary? Isn't the "each $dance" just a
bassackwards method invocation (as C<close $fh> is to C<$fh.close()>)?
> Then there's this approach to auto-iteration:
>
> my @dance := Iterator.new(@squares);
> for @dance {
I think this is called "avoiding the question". Now you've converted an
Iterator into an iterator masked behind an array, and asked the C<for>
keyword to create apparently a "private" iterator to traverse it. That
seems like twice as much work for the same output.
Also, I have a problem with the notion of the Iterator class being
tasked with creation of iterators -- how do you deal with objects (even
TIEd arrays) that require magic iterators? Better to ask the class to
give you one. (Of course, C<Iterator.new()> could internally ask
@squares to provide an iterator, but again that adds a layer for little
apparent gain.
> Damian Conway wrote:
> 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
What's the value of C<next(PARAM_LIST)>? Is this just a shortcut for
re-initializing the iterator? How is this going to work when the
iterator has opened files or TCP connections based on the parameter
list?
my $iter = DNS.iterator(".com.");
while <$iter> {
$iter.next(".com.au.")
if not hackable($_);
}
Furthermore, what's the syntax for including arguments to next in a
diamond operator?
while <$iter>($a, $b) {
...
$a += 2;
}
> each() # returns a lazy array, each element of which
> # is computed on demand by the appropriate
> # number of resumptions of the coroutine body
What's the difference between a lazy array and an iterator? Is there
caching? What about the interrelationships between straight iteration
and iteration interrupted by a reset of the parameter list? Or does
calling $iter.next(PARAM_LIST) create a new iterator or wipe the cache?
How do multiple invocations of each() interact with each other? (E.g.,
consider parsing a file with block comment delimiters: one loop to read
lines, and an inner loop to gobble comments (or append to a delimited
string -- same idea). These two have to update the same file pointer,
or all is lost.)
Some of questions about iterators and stuff:
1- Are iterators now considered a fundamental type?
1a- If so, are they iterators or Iterators? (See 2b1, below)
1b- What value would iterators (small-i) have? Is it a meaningful idea?
2- What is the relationship between iterators and arrays/lists?
2a- Is there an C<Iterator.toArray()> or C<.toList()> method?
2a1- The notion that Iterator.each() returns a lazy array seems a
little wierd. Isn't a lazy array just an iterator? Why else have the
proposed syntax for Iterator.next(PARAM_LIST)? (Admittedly the
PARAM_LIST doesn't have to be a single integer, like an array.) Or is
that what a small-i iterator is?
2b- Is there a C<List.iterator()> method? Or some other standard way of
iterating lists?
2b1- Are these "primitive" interfaces to iteration, in fact
overridable? That is, can I override some "operator"-like method and
change the behavior of
while <$fh> { print; }
2b2- Is that what C<each> does in scalar context -- returns an
iterator?
my $iter = each qw(apple banana cherry);
my $junk = all qw(apple banana cherry);
my $itr2 = each $junk; # Whoops! Wrong thread...
3- What's the difference among an iterator, a coroutine, and a
continuation?
3a- Does imposing Damian's iterator-based semantics for coroutines
(and, in fact, imposing his definition of "any sub-with-yield ==
coroutine") cause loss of desirable capability? (Asked in ignorance --
the only coroutines I've ever dealt with were written in assembly
language, so I don't really know anything about what they can be used
to do.)
3b- Is there a corresponding linkage between continuations and some
object, a la coroutine->iterator?
3c- Is there a tie between use of continuations and use of thread or
IPC functionality? Is it a prohibitive tie, one way or the other? That
is, I've been thinking that "A coroutine is just a continuation." But
if "A continuation implies <...>", for example a semaphore or a thread,
or some such, then that may be too expensive. (More ignorance on my
part, I'm sure.)
3d- Conversely, what happens when continuations, coroutines, or
iterators are used in a threaded environment? Will there need to be
locking?
4- Given the historical behavior of binding $_ to the actual data in
question (thus making it modifiable via $_) what's the correct behavior
for iterators? Will they "upvar", or return a ref, or what? How do I
write that?
sub fibs()
{
my ($a, $b) = (0, 1);
loop {
yield $b;
($a, $b) = ($b, $b + $a);
}
}
for <fibs()> {
when 13 { $_ = 100; }
print "$_\n";
}
DWIM? ( ... 5, 8, 13, 100, 113, ... )
> In a scalar context:
>
> <$fh> # Calls $fh.readline (or maybe that's $fh.next???>
I think it's $fh.next. $fh.next calls $fh.readline, or not, or is :=
$fh.readline, or whatever. Keep it simple.
my $i = 0;
while <$i> {
Should integer.next() be operator:++ ? :-)
> <$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)
(FWIW: I think they call .next(), and .next() can call the input
retrieval coroutine or not.)
Okay, I think I'm seeing why the lazy array bit is needed.
So is it true that an iterator must be arrayificable? Or listificable?
Also, what happens when <$fh> or <$iter> is called in scalar context
within a loop? Surely that must update the "secret" iterator that is
being run by the loop control?
That is:
for <$fh> {
...
if /$start_of_block/ {
my $block = "";
while <$fh> {
leave loop if /$end_of_block/;
$block ~= $_; # Or WFE the string concat operator winds up.
}
}
}
The two loops must update the same iterator, so any "lazy array" bits
have to update as well. Ah well, that's for Dan &co.
=Austin