|
| 1 | + |
| 2 | +=encoding utf8 |
| 3 | + |
| 4 | +=head1 TITLE |
| 5 | + |
| 6 | +Synopsis 7: Lists and Iteration [DRAFT] |
| 7 | + |
| 8 | +=head1 VERSION |
| 9 | + |
| 10 | + Created: 11 June 2015 |
| 11 | + |
| 12 | + Last Modified: 11 June 2015 |
| 13 | + Version: 1 |
| 14 | + |
| 15 | +=head1 Overview |
| 16 | + |
| 17 | +Lists and arrays have always been one of Perl's fundamental data types, |
| 18 | +and Perl 6 is no different. However, lists in Perl 6 have been greatly |
| 19 | +extended to accommodate lazy lists, infinite lists, lists of mutable |
| 20 | +and immutable elements, typed lists, flattening behaviors, and so on. |
| 21 | +So where lists and arrays in Perl 5 tended to be finite sequences of |
| 22 | +scalar values, in Perl 6 we have additional dimensions of behavior |
| 23 | +that must be addressed. |
| 24 | + |
| 25 | +This document describes the post-GLR design for lists in Perl 6. |
| 26 | +Some portions may contain a fair bit of guesswork. |
| 27 | + |
| 28 | +=head2 The C<List> type |
| 29 | + |
| 30 | +The C<List> class is the base class for dealing with other types of |
| 31 | +lists, including C<Array>. To the programmer, a C<List> is a potentially |
| 32 | +lazy and infinite sequence of elements. |
| 33 | + |
| 34 | +Lists may be mutable, in that one can manipulate the sequence via |
| 35 | +operations such as C<push>, C<pop>, C<shift>, C<unshift>, C<splice>, |
| 36 | +etc. A C<List>'s elements may be either mutable or immutable. |
| 37 | + |
| 38 | +C<List> objects are C<Positional>, meaning they can be bound to |
| 39 | +array variables and support the postfix C<.[]> operator. |
| 40 | + |
| 41 | +Lists are also lazy, in that the elements of a C<List> may |
| 42 | +come from generator functions that produce elements on demand. |
| 43 | + |
| 44 | +The comma operator (C<< infix:<,> >>) creates (possibly immutable) |
| 45 | +C<List> objects. The elements of such a list may be mutable or |
| 46 | +immutable. Except for empty lists, parentheses are not used in the |
| 47 | +creation of C<List> objects. |
| 48 | + |
| 49 | + () # empty List |
| 50 | + (1) # an Int |
| 51 | + (1,2) # a List with two Ints |
| 52 | + (1,) # a List with one Int |
| 53 | + |
| 54 | +=head2 The C<Array> type |
| 55 | + |
| 56 | +An C<Array> is simply a C<List> in which all of the elements are held |
| 57 | +in scalar containers. This allows assignment to the elements of the |
| 58 | +array. |
| 59 | + |
| 60 | +=head2 Flattening contexts |
| 61 | + |
| 62 | +C<List> and objects can have other container objects as elements. |
| 63 | +In some contexts we want to interpolate the values of container |
| 64 | +objects into the surrounding C<List>, while in other contexts we |
| 65 | +want any subcontainers to be preserved. Such interpolation is |
| 66 | +known as "flattening". |
| 67 | + |
| 68 | +The <Iterable> type is performed by container and generator objects |
| 69 | +that will interpolate their values in flattening contexts. C<List>, |
| 70 | +and C<Range> objects are C<Iterable>. |
| 71 | + |
| 72 | +Flattening occurs when assigning or initializing an array: |
| 73 | + |
| 74 | + my @a = 3, 4, 5; |
| 75 | + my @b = 1, 2, @a, 6..9; # @b has nine elements |
| 76 | + |
| 77 | + my @c; |
| 78 | + @c = 1, 2, @a; # @c has five elements |
| 79 | + |
| 80 | +Flattening also occurs using the C<flat> contextualizer: |
| 81 | + |
| 82 | + for 1, 2, @a { ... } # three iterations |
| 83 | + for flat 1, 2, @a { ... } # five iterations |
| 84 | + |
| 85 | +Slurpy array parameters declared with a single C<*> marker lazily |
| 86 | +flatten the arguments into the array. |
| 87 | + |
| 88 | +Conjecture: An array constructor preceded by a colon flattens its |
| 89 | +interior contents. Array constructors without the colon do not flatten |
| 90 | +the interior. |
| 91 | + |
| 92 | + my $d = :[ 1, <a b c> ] # four elements, [ 1, 'a', 'b', 'c' ] |
| 93 | + my $e = [ 1, <a b c> ] # two elemetns, [ 1, ('a', 'b', 'c') ] |
| 94 | + |
| 95 | +Objects held in scalar containers are never interpolated in flattening |
| 96 | +context, even if the object is C<Iterable>. |
| 97 | + |
| 98 | + my @a = 3, 4, 5; |
| 99 | + my @b = 1, 2, @a; # @b has five elements |
| 100 | + |
| 101 | + my $s = @a; |
| 102 | + my @c = 1, 2, $s; # @c has three elements |
| 103 | + |
| 104 | +Here, both C<$s> and C<@a> refer to the same underlying C<Array> object, |
| 105 | +but the presence of the scalar container prevents C<$s> from being |
| 106 | +flattened into C<@c>. The C<.list> or C<.flat> method may be used |
| 107 | +to restore the flattening behavior: |
| 108 | + |
| 109 | + my @d = 1, 2, $s.list # @d has five elements |
| 110 | + my @d = 1, 2, @($s) # @d has five elements |
| 111 | + |
| 112 | +Conversely, the C<.item> or C<$()> contextualizer can be used to |
| 113 | +prevent an C<Iterable> from being interpolated: |
| 114 | + |
| 115 | + my @a = 3, 4, 5; |
| 116 | + my @b = 1, 2, @a; # @b has five elements |
| 117 | + my @c = 1, 2, $(@a); # @c has three elements |
| 118 | + |
| 119 | +=head2 Iterables and Iterators |
| 120 | + |
| 121 | +This section gives information about C<Iterable> and C<Iterator> objects. |
| 122 | + |
| 123 | +=head3 The C<.infinite> method |
| 124 | + |
| 125 | +Because lists in Perl 6 can be lazy, they can also be infinite. |
| 126 | +Each C<Iterator> must provide an C<.infinite> method, which returns |
| 127 | +a value indicating the knowable finiteness of the iteration: |
| 128 | + |
| 129 | + .infinite Meaning |
| 130 | + ---------------------------------------------- |
| 131 | + True iteration is known to be infinite |
| 132 | + False iteration is known to be finite |
| 133 | + Mu finiteness isn't currently known |
| 134 | + |
| 135 | +As an example, C<Range> iterators can generally know finiteness simply |
| 136 | +by looking at the endpoint of the C<Range>. The iterator for the |
| 137 | +C<< infix:<...> >> sequence operator treats any sequence ending in |
| 138 | +C<*> as being "known infinite", all other C<...> sequences have unknown |
| 139 | +finiteness. In the general case it's not possible for loop iterators |
| 140 | +to definitively know if the sequence will be finite or infinite. |
| 141 | +(Conjecture: There will be a syntax or mechanism for the programmer |
| 142 | +to indicate that such sequences are to be treated as known finite |
| 143 | +or known infinite.) |
| 144 | + |
| 145 | +=head1 DISCUSSION |
| 146 | + |
| 147 | +During the draft phases of this document, feel free to add questions |
| 148 | +and/or discussion points here. Links to #perl6 logs are acceptable. |
| 149 | + |
| 150 | +=over 4 |
| 151 | + |
| 152 | +=item * |
| 153 | + |
| 154 | +Pm thinks/remembers that people preferred C<Iterable> to be a role |
| 155 | +instead of a class. |
| 156 | + |
| 157 | +=back |
| 158 | + |
| 159 | +=head1 AUTHORS |
| 160 | + |
| 161 | + Patrick R. Michaud <pmichaud@pobox.com |
| 162 | + |
| 163 | +=for vim:set expandtab sw=4: |
0 commit comments