Austin Hastings wrote:

   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?
It's the way we mark an indirect object in Perl 6.


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()>)?
Yes. The colon is needed because the colon-less Perl 5 indirect object
syntax is inherently ambiguous. Adding the colon in Perl 6 fixes the
many nasty, subtle problems that Perl 5's syntax had.


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.
There's no second iterator. Just C<for> walking through an array.


What's the value of C<next(PARAM_LIST)>? Is this just a shortcut for
re-initializing the iterator?
No. It uses the original coroutine but rebinds its parameters to the new
arguments passed to C<next>.


How is this going to work when the
iterator has opened files or TCP connections based on the parameter
list?
The original files or connections will be unaffected.


Furthermore, what's the syntax for including arguments to next in a
diamond operator?
I very much doubt there would be one. If you need to pass arguments,
you'd call C<next> explicitly.


What's the difference between a lazy array and an iterator? Is there
caching?
Yes. A lazy array is a wrapper-plus-cache around an iterator.


What about the interrelationships between straight iteration
and iteration interrupted by a reset of the parameter list?
Resetting the parameter list doesn't interrupt iteration.


> Or does
calling $iter.next(PARAM_LIST) create a new iterator or wipe the cache?
No.


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.)
So pass the file pointer to the original continuation.


Some of questions about iterators and stuff:

1- Are iterators now considered a fundamental type?
Probably, since they're fundamental to I/O and C<for> loops.


1a- If so, are they iterators or Iterators? (See 2b1, below)
class Iterator {...}


1b- What value would iterators (small-i) have? Is it a meaningful idea?
Depends what you mean by it. ;-)


2- What is the relationship between iterators and arrays/lists?
None. Except that some arrays/lists may be implemented using Iterators.


2a- Is there an C<Iterator.toArray()> or C<.toList()> method?
Iterator::each.


2a1- The notion that Iterator.each() returns a lazy array seems a
little wierd. Isn't a lazy array just an iterator?
No. It's an array that populates itself on-demand using an iterator.


2b- Is there a C<List.iterator()> method? Or some other standard way of
iterating lists?
Probably.


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; }
Sure. Derive a class from Iterator and change its C<next> method.


2b2- Is that what C<each> does in scalar context -- returns an
iterator?
No. C<each> returns a lazy array, so in a scalar context it returns
a reference to the lazy array.


3- What's the difference among an iterator, a coroutine, and a
continuation?
Iterator: an object that returns successive values from some source
	  (such as an array, a filehandle, or a coroutine)

Coroutine: a subroutine whose state is preserved when it returns
           such that it may be restarted from the point of previous
	   return, rather than from the start of the subroutine

Continuation: a mechanism for capturing the "what-happens-next"
	      at any point in a program's execution

BTW, there's rather a nice discussion of these three at:
http://mail.python.org/pipermail/python-dev/1999-July/000467.html


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?
No. Not compared to other potential coroutine semantics.


> 3b- Is there a corresponding linkage between continuations and some
object, a la coroutine->iterator?
Continuations can be used to implement virtually any control structure.
In a sense they link to everything.


3c- Is there a tie between use of continuations and use of thread or
IPC functionality?
Hmmm. I *suppose* a continuation could continue into a different thread.
That might be something worth proscribing. ;-)



3d- Conversely, what happens when continuations, coroutines, or
iterators are used in a threaded environment? Will there need to be
locking?
Yes. Threaded environments *always* require locking at some level.


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?
C<yield> is just a C<return> that can...err...come back. So, if you
want to return an lvalue, you declare the coroutine to do so:

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

    for <fibs()> {
        when 13 { $_ = 100; }

        print "$_\n";
    }

Of course, given the implementation of C<fibs>
that will print: 1, 1, 2, 3, 5, 8, 100, 108, 208, 316, etc.



my $i = 0;
while <$i> {
Should integer.next() be operator:++ ? :-)
No! ;-)



So is it true that an iterator must be arrayificable? Or listificable?
If a class inherits from Iterator, it will automatically have the
appropriate C<each> method that wraps its associated coroutine in an array.
If you chose to override that functionality, well, _caveat derivor_!


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.
It means that the lazy array will not contain the lines that were read
by the inner iteration. So the code will behave as expected (i.e. process
each line from the file exactly once).

Damian

Reply via email to