Luke Palmer enquired:

we still have implicit iteration:

    for fibs() {
        print "Now $_ rabbits\n";
    }
Really? What if fibs() is a coroutine that returns lists (Fibonacci
lists, no less), and you just want to iterate over one of them? The
syntax:

for &fibs {
print "Now $_ rabbits\n";
}

Would make more sense to me for implicit iteration. Perhaps I'm not
looking at it right. How could you get the semantics of iterating
over just one list of the coroutine?
The semantics of C<for> would simply be that if it is given an iterator
object (rather than a list or array), then it calls that object's iterator
once per loop.


and explicit iteration:

    my $iter = fibs();
    while <$iter> {
        print "Now $_ rabbits\n";
    }

Ahh, so $iter is basically a structure
It's an object.


that has a continuation and a
value.  When you call the .next method, it calls the continuation, and
delegates to the value otherwise.
Err. No. Not quite. Though that would be cute too.


(Unless the coroutine itself is returning iterators...
Yep.

The idea is that, when any subroutine (&f) with a C<yield> in it is called,
it immediately returns an Iterator object (i.e. without executing its body at
all). That Iterator object has (at least) two C<next> methods:

	method next() {...}
	method next(...) {...}

where the second C<next>'s parameter list is identical to the
parameter list of the original &f.

Code can then call the iterator's C<next> method, either explicitly:

	$iter.next(...);

or operationally:

	<$iter>

or implicitly (in a C<for> loop):

	for $iter {...}

Previously Larry has written that last variant as:

	for <$iter> {...}

but I think that's...err...differently right. I think the angled version
should invoke C<$iter.next> once (before the C<for> starts iterating) and
then iterate the result of that. In other words, I think that a C<for>
loop argument should always have one implicit level of iteration.

Otherwise I can't see how one call call an iterator directly in a
for loop:

	for <fibs()> {...}


But I could certainly live with it not having that, in which case
the preceding example would have to be:

	my $iter = fibs();
	for <$iter> {...}


and, if your coroutine itself repeatedly yields a iterator
then you need:

	my $iter = fibses();
	for < <$iter> > {...}

(Careful with those single angles, Eugene!)


    class Foo {
        method next { print "Gliddy glub gloopy\n" }
    }
    sub goof () {
	loop {
            print "Nibby nabby nooby\n";
            yield new Foo;
That would have to be:

              yield new Foo:;
or:
              yield Foo.new;

}
}
my $iter = goof;
print $iter.next; # No.. no! Gliddy! Not Nibby!

How does this work, then?
Calling C<goof> returns an iterator that resumes the body of C<goof>
each time the iterator's C<next> method is called.

Teh actual call to C<$iter.next> resumes the body of C<goof>, which runs
until the next C<yield>, which (in this case) returns an object of class
C<Foo>. So the line:

	print $iter.next;

prints "Nibby nabby nooby\n" then the serialization of the Foo object.

If you wanted to print "Nibby nabby nooby\n" and then "Gliddy glub gloopy\n"
you'd write:

	print $iter.next.next;
or:
	print <$iter.next>;
or:
	print < <$iter> >;


Hang on... is C<while> a topicalizer now?
That's still under consideration. I would like to see the special-case
Perl 5 topicalization of:

	while <$iter> {...}

to be preserved in Perl 6. Larry is not so sure. If I can't sway Larry, then
we'd need explicit topicalization there:

	while <$iter> -> $_ {...}

which in some ways seems like a backwards step to me.



So filehandles are just loops that read lines constantly and yield
them.
Nearly. Filehandles are just iterator objects, each attached to a
coroutine that reads lines constantly and yields them.


I'm really starting to like the concept of those co-routines :)
Likewise.


They elegantify stuff.
<tsk> <tsk> If you're going to talk Merkin, talk it propericiously:

	"They elegantificatorize stuff"

;-)

Damian

Reply via email to