> 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

Reply via email to