Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
GLRify List.pod
  • Loading branch information
moritz committed Sep 27, 2015
1 parent 4801399 commit 645466d
Showing 1 changed file with 96 additions and 100 deletions.
196 changes: 96 additions & 100 deletions lib/Type/List.pod
Expand Up @@ -18,7 +18,7 @@ Arrays to have every value of the list stored in a container.
In Perl 6, assigning a C<List> to a scalar variable does not lose
information. The difference is that iteration generally treats a
list (or any other list-like object, like a L<Seq> or an L<Array>)
inside a scalar as a single element.
inside a scalar as a single element, as long as it's part of another .
my @a = 1, 2, 3;
for @a { } # three iterations
Expand All @@ -28,16 +28,40 @@ inside a scalar as a single element.
for @a.item { } # one iteration
for $s.list { } # three iterations
Lists generally interpolate (flatten) unless they are accessed via
an item (scalar) container.
Lists generally don't interpolate (flatten) into other lists, except
when they are not itemized, and the single argument to an operation
such as C<push>:
my @a = 1, 2, 3;
my @flat = @a, @a; # six elements
my @nested = @a.item, @a.item; # two elements
my @nested = @a, @a; # two elements
my @flat = flat @a, @a; # six elements, with explict flat
my @b = 'a', 'b';
@b.push: @a; # @b now has 5 elements, because @a
# is the sole argument to push
my @c = 'a', 'b';
@c.push: @a, ; # @b now has 3 elements, because of the
# trailing comma
my @c = 'a', 'b';
@c.push: $@a; # @b now has 3 arguments, because @a was
# itemized
C<.item> can often be written as C<$( ... )>, and on an array variable
even as C<$@a>.
The same flattening behavior applies all objects that do the
L<Iterable|/type/Iterable> role, notable L<hashes|/type/Hash>:
my %h = a => 1, b => 2;
my @b = %h; say @b.elems; # 2
my @c = %h, ; say @c.elems; # 1
my @d = $%h; say @d.elems; # 1
Slurpy parameters (C<*@a>) flattens non-itemized sublists:
sub fe(*@flat) { @flat.elems }
say fe(<a b>, <d e>); # 4
say fe(<a b>, <d e>.item); # 3
=head1 Methods
=head2 routine elems
Expand All @@ -56,40 +80,40 @@ Returns the index of the last element.
=head2 routine keys
multi sub keys($list) returns List:D
multi method keys(List:D:) returns List:D
multi sub keys($list) returns Seq:D
multi method keys(List:D:) returns Seq:D
Returns a list of indexes into the list (e.g., 0..(@list.elems-1)).
Returns a sequence of indexes into the list (e.g., 0..(@list.elems-1)).
=head2 routine values
multi sub values($list) returns List:D
multi method values(List:D:) returns List:D
multi sub values($list) returns Seq:D
multi method values(List:D:) returns Seq:D
Returns a copy of the list.
Returns a sequence of the list elements, in order.
=head2 routine kv
multi sub kv($list) returns List:D
multi method kv(List:D:) returns List:D
multi sub kv($list) returns Seq:D
multi method kv(List:D:) returns Seq:D
Returns an interleaved list of indexes and values. For example
Returns an interleaved sequence of indexes and values. For example
<a b c>.kv
Returns
0, 'a', 1, 'b', 2, 'c'
(0, 'a', 1, 'b', 2, 'c').Seq
=head2 routine pairs
multi sub pairs($list) returns List:D
multi method pairs(List:D:) returns List:D
multi sub pairs($list) returns Seq:D
multi method pairs(List:D:) returns Seq:D
Returns a list of pairs, with the indexes as keys and the list values as
Returns a sequence of pairs, with the indexes as keys and the list values as
values.
<a b c>.pairs # 0 => 'a', 1 => 'b', 2 => 'c'
<a b c>.pairs # (0 => 'a', 1 => 'b', 2 => 'c').Seq
=head2 routine join
Expand All @@ -109,11 +133,11 @@ Note that the method form does not flatten sublists:
=head2 routine map
multi sub map(&code, *@elems) returns List:D
multi method map(List:D: &code) returns List:D
multi sub map(&code, *@elems) returns Seq:D
multi method map(List:D: &code) returns Seq:D
Invokes C<&code> for each element and gathers the return values in another
list and returns it. This happens lazily, i.e. C<&code> is only invoked when
Invokes C<&code> for each element and gathers the return values in
a sequence and returns it. This happens lazily, i.e. C<&code> is only invoked when
the return values are accessed.
Examples:
Expand All @@ -136,12 +160,12 @@ Note that C<map> does not flatten embedded lists and arrays, so
((1, 2), <a b>).map({ .join(',')})
passes C<(1, 2)> and C<< <a b> >> in turn to the block, leading to a total
of two iterations and the result list C<"1,2", "a,b">.
of two iterations and the result sequence C<"1,2", "a,b">.
See L<method flatmap|#method flatmap> for an alternative that flattens.
=head2 method flatmap
method flatmap(List:D: &code) returns List:D
method flatmap(List:D: &code) returns Seq:D
Like C<map> iterates over the elements of the invocant list, feeding each
element in turn to the code reference, and assembling the return values from
Expand All @@ -155,10 +179,10 @@ invokes C<uc|/type/Str#routine uc> four times.
=head2 routine grep
multi sub grep(Mu $matcher, *@elems) returns List:D
multi method grep(List:D: Mu $matcher) returns List:D
multi sub grep(Mu $matcher, *@elems) returns Seq:D
multi method grep(List:D: Mu $matcher) returns Seq:D
Returns a lazy list of elements against which C<$matcher> smart-matches.
Returns a sequence of elements against which C<$matcher> smart-matches.
The elements are returned in the order in which they appear in the original
list.
Expand All @@ -171,9 +195,9 @@ Examples:
=head2 routine grep-index
multi method grep-index(List:D: Mu $matcher) returns List:D
multi method grep-index(List:D: Mu $matcher) returns Seq:D
Returns a lazy list of indices against which the associated elements
Returns a sequence of indices against which the associated elements
smart-match. The indices are returned in order.
=head2 routine first
Expand Down Expand Up @@ -251,8 +275,8 @@ Returns the number of elements in the list (same as C<.elems>).
=head2 routine pick
multi sub pick($count, *@list) returns List:D
multi method pick(List:D: $count = 1)
multi sub pick($count, *@list) returns Seq:D
multi method pick(List:D: $count = 1) returns Mu
Returns C<$count> elements chosen at random and without repetition
from the invocant. If C<*> is passed as C<$count>, or C<$count> is
Expand All @@ -263,20 +287,20 @@ Examples:
say <a b c d e>.pick; # b
b
say <a b c d e>.pick: 3; # c a e
say <a b c d e>.pick: *; # e d a b c
say <a b c d e>.pick: 3; # (c a e)
say <a b c d e>.pick: *; # (e d a b c)
=head2 routine roll
multi sub roll($count, *@list) returns List:D
multi sub roll($count, *@list) returns Seq:D
multi method roll(List:D: $count = 1)
Returns a lazy list of C<$count> elements, each randomly selected from the
Returns a sequence of C<$count> elements, each randomly selected from the
list. Each random choice is made independently, like a separate die roll
where each die face is a list element.
If C<*> is passed to C<$count>, returns a lazy, infinite list of randomly chosen
elements from the original list.
If C<*> is passed to C<$count>, returns a lazy, infinite sequence of randomly
chosen elements from the original list.
Examples:
Expand All @@ -294,8 +318,6 @@ Examples:
sub eager(*@elems) returns List:D
Evaluates all elements in the list eagerly, and returns them as a list.
If a List signals that it is "known infinite", eager evaluation may
stop at the point where the infinity is detected.
=head2 routine reverse
Expand Down Expand Up @@ -326,10 +348,10 @@ Examples:
=head2 routine sort
multi sub sort(*@elems) returns List:D
multi sub sort(&by, *@elems) returns List:D
multi method sort(List:D:) returns List:D
multi method sort(List:D:, &by) returns List:D
multi sub sort(*@elems) returns Seq:D
multi sub sort(&by, *@elems) returns Seq:D
multi method sort(List:D:) returns Seq:D
multi method sort(List:D:, &by) returns Seq:D
Sorts the list, smallest element first. By default C<< infix:<cmp> >>
is used for comparing list elements.
Expand All @@ -350,10 +372,10 @@ Examples:
=head2 routine unique
multi sub unique(*@values, :&as) returns List:D
multi method unique(List:D:, :&as) returns List:D
multi sub unique(*@values, :&as) returns Seq:D
multi method unique(List:D:, :&as) returns Seq:D
Returns a list of unique values from the invocant/argument list, such
Returns a sequence of unique values from the invocant/argument list, such
that only the first occurrence of each duplicated value remains in the
result list. C<unique> uses the semantics of the L<===> operator to decide whether
two objects are the same. The order of the original list is preserved even as
Expand All @@ -377,10 +399,10 @@ Example:
=head2 routine squish
multi sub squish(*@values, :&as) returns List:D
multi method squish(List:D:, :&as) returns List:D
multi sub squish(*@values, :&as) returns Seq:D
multi method squish(List:D:, :&as) returns Seq:D
Returns a list of values from the invocant/argument list where runs
Returns a sequence of values from the invocant/argument list where runs
of more than one value are replaced with only the first instance.
Like L<C<unique>>, C<squish> uses the semantics of the L<===> operator to decide
whether two objects are the same. Unlike L<C<unique>>, this function only
Expand Down Expand Up @@ -429,9 +451,9 @@ Example:
=head2 routine combinations
multi method combinations (List:D: Int:D $of) returns List:D
multi method combinations (List:D: Range:D $of = 0..*) returns List:D
multi sub combinations ($n, $k) returns List:D
multi method combinations (List:D: Int:D $of) returns Seq:D
multi method combinations (List:D: Range:D $of = 0..*) returns Seq:D
multi sub combinations ($n, $k) returns Seq:D
The C<Int> variant returns all C<$of>-combinations of the invocant list.
For example
Expand Down Expand Up @@ -477,10 +499,10 @@ prints
=head2 routine permutations
multi method permutations(List:D:) returns List:D
multi sub permutations($n) returns List:D
multi method permutations(List:D:) returns Seq:D
multi sub permutations($n) returns Seq:D
Returns all possible permutations of a list as a list of arrays. So
Returns all possible permutations of a list as a sequence of lists. So
say .join('|') for <a b c>.permutations
Expand Down Expand Up @@ -513,9 +535,9 @@ prints
=head2 method rotor
method rotor(*@cycle, Bool() :$partial)
method rotor(*@cycle, Bool() :$partial) returns Seq:D
Returns a list of lists, where each sublist is made up of elements of the
Returns a sequence of lists, where each sublist is made up of elements of the
invocant.
In the simplest case, C<@cycle> contains just one integer, in which case the
Expand Down Expand Up @@ -544,59 +566,33 @@ Combining multiple cycles and C<:partial> also works:
say ('a'..'h').rotor(1 => 1, 3 => -1, :partial).join('|');
# a|c d e|e|g h
Note that assigning the list of lists returned from C<rotor> to a variable
will flatten to an C<Array>:
my @maybe_lol = ('a'..'h').rotor(2 => 1);
@maybe_lol.perl.say; #-> ["a", "b", "d", "e", "g", "h"]<>
Which probably isn't what one wanted, since the C<rotor>-ed output looks
like this:
say ('a'..'h').rotor(2 => 1).perl; #-> (("a", "b"), ("d", "e"), ("g", "h"))
To force a C<List> of C<List>s to be returned, I<bind> the output instead of
assigning it:
my @really_lol := ('a'..'h').rotor(2 => 1);
@really_lol.perl.say; #-> (("a", "b"), ("d", "e"), ("g", "h"))
=head2 routine zip
sub zip(List:D:, List:D:, ...) returns Seq:D
sub zip(**@e) returns Seq:D
Zip two or more lists together by interleaving their elements. If the lists
have different lengths, then the lists are zipped to the length of the
shortest list; elements of the longer list(s) are discarded.
Zips two or more lists or other L<iterables|/type/Iterable> together by
returning a sequence made of a list of all first elements of all lists, then a
list of all second elemnts of a list etc.
In order to support parallel iteration over multiple arrays, Perl 6
has a C<zip> function that builds a list of C<List> objects from the
elements of two or more arrays. In ordinary list context this behaves
as a list of C<Captures> and automatically flattens.
say .join for zip <a b c>, <d e f>;
=comment TODO: GLR
Produces the output
for zip(@names; @codes) -> $name, $zip {
say "Name: $name; Zip code: $zip";
}
ad
be
cf
C<zip> has an infix synonym, the C<Z> operator.
In an explicitly multidimensional list context, however, the sequences
turn into subarrays, and each element would then have to be unpacked
by the signature:
say .join for <a b c> Z <d e f>; # same output as above
for lol(zip(@names; @codes)) -> [$name, $zip] {
say "Name: $name; Zip code: $zip";
}
When the first input list is exhausted, no more elements are returned; so
trailing elements from longer input lists are discarded.
By default the C<zip> function reads to the end of the shortest list, but a
short list may always be extended arbitrarily by putting C<*> after the
final value, which replicates the final value as many times as necessary.
If instead of supplying a default value for short lists, you just wish to
skip missing entries, use L<roundrobin|/type/List#sub_roundrobin> instead:
If you just wish to skip missing entries in shorter sublists,
use L<roundrobin|/type/List#sub_roundrobin> instead:
for roundrobin(@queue1; @queue2; @queue3) -> $next {
for roundrobin(@queue1, @queue2, @queue3) -> $next {
...
}
Expand All @@ -611,7 +607,7 @@ elements but simply skip any undefined value:
my @a = 1;
my @b = 1..2;
my @c = 1..3;
for roundrobin(@a; @b; @c) -> $x { $x.say }
for flat roundrobin(@a, @b, @c) -> $x { $x.say }
will display the following values: C<1, 1, 1, 2, 2, 3>
Expand Down

0 comments on commit 645466d

Please sign in to comment.