Perl6-Doc
view release on metacpan or search on metacpan
share/Synopsis/S07-iterators.pod view on Meta::CPAN
@it.pop; # Eagerness happens. Maybe bad things, too.
...but you had better be very sure that the list is finite. Attempts to
fiddle with the end of an infinite list may result in the interpreter
raising quite the exception, in the luckiest cases it may just deliver an
C<Inf>, but in some cases you may find yourself spending a very, very
long time doing laps around the yard. The exact behavior may be
implementation specific.
So don't do that.
If the list is known to be finite, the generic array iterator will
revert to a normal array once the feed is exhausted. So it is legal
to:
@it.push; # eagerly exhausts the feed, then turns into to a normal array
...with the same caveats about infinity.
(XXX TODO: effect of type constraints/shape of @it? )
(XXX TODO:
my @a = (1,2); @a <<== ... promotes an occupied Positional to
iterator, right? Should probably be explicitly mentioned.
)
=head2 Generic Lazy Slice
The generic lazy slice consumes the C<Parcel>s from an iterator but
stores the results as a bi-dimensional list, where the first dimension
corresponds to an iteration, and the second contains the values in
the C<Parcel> returned for that iteration, but turned into a C<Seq> object.
Empty C<Parcel> objects are turned into empty C<Seq> objects.
Any other object is returned as itself.
To obtain a generic lazy slice, end a feed in a sliced binding.
my **@it <== map { ... }, 1,2,3;
Note that in:
my **@it <== (1,mysub(),2; 1..*);
the slice lists are independently lazy. However, the call to
C<mysub()> is not particularly lazy; it occurs when the parcel is
constructed. Any laziness is in the function's return value, not in
the call. A call in the top level of any parcel is called eagerly.
To call a function lazily it is necessary to embed the call in some
other explicitly lazy operator:
1, (() ... { START mysub() }), 2 # harder way
1, lazy { mysub() }, 2 # easier way
[Note: the above text really belongs somewhere else, but I'm too lazy to
figure out where.]
=head1 Coroutines
Perl6 does not have a formally defined sub-style coroutine. Doubtless
there will be external modules to do so in different flavors. Such a
construct, where many calls made to the name of a sub with different
parameters, expecting to reach the same sub every time, is not really
compatible with multi-method-dispatch. While it may suit some
programming styles which only use a subset of the Perl6 language, it
cannot be made generally applicable across the Perl6 feature set.
This is not to say you cannot do coroutines in Perl6. In fact, the
gather/take construct is a simple coroutine. But if you want to pass
values back and forth Lua-style, you have to use a suplimentary
object:
sub my_coro (*@slurp) {
gather do {
my Int $initval;
my Str $secondval;
my Int $thirdval;
$initval = shift(@slurp);
$initval++;
take $initval;
$secondval = shift(@slurp);
take "$initval $secondval";
$thirdval = shift(@slurp);
take $thirdval + $initval;
}
}
my @a = (1);
my $it;
$it <== my_coro() <== while 1 { shift(@a) };
say "First result: " ~ get $it;
@a.push("Hello World");
say "Second result: " ~ get $it;
@a.push(500);
say "Third result: " ~ get $it;
...if you want to pass multiple parameters on each call, you can
use a slice slurpy instead, to pass a C<Capture>.
The iterator and array can of course be bundled up to give a more
natural feel:
class my_sub2coro {
has $!it = Failure;
has @!data = ();
has $.coro;
submethod BUILD {
$!it <== &($.coro)() <== while 1 { shift(@!data) };
}
method corocall($message) {
@!data.push($message);
get $!it;
}
}
my $c = my_sub2coro.new(coro => &my_coro);
say "First result" ~ $c.corocall(1);
say "Second result" ~ $c.corocall("Hello World");
say "Third result" ~ $c.corocall(500);
(XXX TODO: As feeds are not implemented yet, above example code not tested)
=head1 Additions
Please post errors and feedback to perl6-language. If you are making
a general laundry list, please separate messages by topic.
( run in 0.771 second using v1.01-cache-2.11-cpan-39bf76dae61 )