|
| 1 | +=begin pod |
| 2 | +
|
| 3 | +=TITLE Lists, Sequences, and Arrays |
| 4 | +
|
| 5 | +=SUBTITLE Positional data constructs |
| 6 | +
|
| 7 | +Lists have been a central part of computing since before there |
| 8 | +were computers, during which time many devils have taken up residence in |
| 9 | +their details. They were actually one of the hardest parts of Perl 6 |
| 10 | +to design, but through persistence and patience, Perl 6 has arrived with |
| 11 | +an elegant system for handling them. |
| 12 | +
|
| 13 | +=head1 Literal Lists |
| 14 | +
|
| 15 | +Literal lists are created with C<,> B<not> with parentheses, so: |
| 16 | +
|
| 17 | + 1,2 # This is two-element list |
| 18 | + (1,2) # This is also a list, in parenthesis |
| 19 | + (1) # This is not a list, just a 1 in parenthesis |
| 20 | + (1,) # This is a one-element list |
| 21 | +
|
| 22 | +Parentheses can be used to mark the beginning and end of a list, so: |
| 23 | +
|
| 24 | + (1,2),(1,2) # This is a list of two lists. |
| 25 | +
|
| 26 | +Individual elements can be pulled out of a list using a subscript. The |
| 27 | +first element of a list is at index number zero: |
| 28 | +
|
| 29 | + say (1,2)[0]; # says 1 |
| 30 | + say (1,2)[1]; # says 2 |
| 31 | + say (1,2)[2]; # says Nil |
| 32 | + say (1,2)[-1]; # Error |
| 33 | +
|
| 34 | +=head1 The @ sigil |
| 35 | +
|
| 36 | +Variables in perl6 whose names bear the C<@> sigil are expected to |
| 37 | +contain some sort of list-like object. Of course, other variables may |
| 38 | +also contain these objects, but C<@>-sigiled variables always do, and |
| 39 | +are expected to act the part. |
| 40 | +
|
| 41 | +By default, when you assign a list to an C<@>-sigiled variable, you create |
| 42 | +an C<Array>. Those are described below. If, instead you want to put an actual |
| 43 | +C<List> into an C<@>-sigiled variable, you can use binding with C<:=> instead. |
| 44 | +
|
| 45 | + my @a := 1,2,3; |
| 46 | +
|
| 47 | +One of the ways C<@>-sigiled variables act like lists is by always supporting |
| 48 | +<positional subscripting|/language/subscripts>. Anything bound to a C<@>-sigiled |
| 49 | +value must support the L</type/positional> role which guarantees this: |
| 50 | +
|
| 51 | + my @a := 1; # Type check failed in binding; expected Positional but got Int |
| 52 | +
|
| 53 | +=head1 Iteration |
| 54 | +
|
| 55 | +All lists may be iterated, which means taking each element from the |
| 56 | +list in order and stopping after the last element: |
| 57 | +
|
| 58 | + for 1,2,3 { .say } # says 1, then says 2, then says 3 |
| 59 | +
|
| 60 | +=head2 Sequences |
| 61 | +
|
| 62 | +Not all lists are born full of elements. Some only create as many elements |
| 63 | +as they are asked for. These are called sequences, which are of type C<Seq>. |
| 64 | +As it so happens, loops return C<Seq>s. |
| 65 | +
|
| 66 | + (loop { 42.say })[2] # says 42 three times |
| 67 | +
|
| 68 | +So, it is fine to have infinite lists in Perl 6, just so long as you never |
| 69 | +ask them for all their elements. In some cases, you may want to avoid |
| 70 | +asking them how long they are too -- Perl 6 will try to return C<Inf> if |
| 71 | +it knows a sequence is infinite, but it cannot always know. |
| 72 | +
|
| 73 | +=comment TODO link or describe C<...> |
| 74 | +
|
| 75 | +Just because you are still allowed to subscript a C<Seq> does not mean it |
| 76 | +promises to keep values around after you have used them. If you have a very |
| 77 | +long sequence, you may want to throw old values away so that memory does |
| 78 | +not fill up. |
| 79 | +
|
| 80 | +=comment TODO document .iterator, .list and .cache |
| 81 | +
|
| 82 | +=head2 Slips |
| 83 | +
|
| 84 | +Sometimes you want to insert the elements of a list into another list. |
| 85 | +This can be done with a special type of sequence called a C<Slip>. |
| 86 | +
|
| 87 | + say (1,(2,3),4) eqv (1,2,3,4) # says False |
| 88 | + say (1,Slip.new(2,3),4) eqv (1,2,3,4) # says True |
| 89 | +
|
| 90 | +Another way to make a slip is with the C<|> prefix operator: |
| 91 | +
|
| 92 | + say (1,|(2,3),4) eqv (1,2,3,4) # says True |
| 93 | +
|
| 94 | +=head1 Immutability |
| 95 | +
|
| 96 | +The lists we have talked about so far (C<List>, C<Seq> and C<Slip>) |
| 97 | +are all immutable. This means you cannot remove elements from them, |
| 98 | +or re-bind existing elements: |
| 99 | +
|
| 100 | + (1,2,3)[0]:delete; # Error Can not remove elements from a List |
| 101 | + (1,2,3)[0] := 0; # Error Cannot use bind operator with this left-hand side |
| 102 | + (1,2,3)[0] = 0; # Error Cannot modify an immutable Int |
| 103 | +
|
| 104 | +However, if any of the elements is wrapped in a L<C<Scalar>|/types/Scalar> you |
| 105 | +can still change the value which that C<Scalar> points to: |
| 106 | +
|
| 107 | + my $a = 2; |
| 108 | + (1,$a,3)[1] = 42; |
| 109 | + $a.say; # says 42 |
| 110 | +
|
| 111 | +...that is, it is only the list structure itself -- how many elements there are |
| 112 | +and each element's identity -- that is immutable. The immutability is not |
| 113 | +contagious past the identity of the element. |
| 114 | +
|
| 115 | +=head1 List Contexts |
| 116 | +
|
| 117 | +So far we have mostly dealt with lists in neutral contexts. Lists are actually |
| 118 | +very context sensitive on a syntactical level. |
| 119 | +
|
| 120 | +=head2 List Assignment Context |
| 121 | +
|
| 122 | +When a list appears on the right hand side of an assignment into a C<@>-sigiled |
| 123 | +variable, it is "eagerly" evaluated. This means that a C<Seq> will be iterated |
| 124 | +until it can produce no more elements. This is one of the places you do not want |
| 125 | +to put an infinite list, lest your program hang and, eventually, run out of memory: |
| 126 | +
|
| 127 | + my $i = 3; |
| 128 | + my @a = (loop { $i.say; last unless --$i }); # Says 3 2 1 |
| 129 | + say "take off!"; |
| 130 | +
|
| 131 | +=head2 Flattening "Context" |
| 132 | +
|
| 133 | +When you have a list that contains sub-lists, but you only want one flat list, |
| 134 | +you may flatten the list to produce a sequence of values as if all parentheses. |
| 135 | +This works no matter how many levels deep the parenthesis are nested. |
| 136 | +
|
| 137 | + say (1,(2,(3,4)),5).flat eqv (1,2,3,4,5) # says True |
| 138 | + for (1,(2,(3,4)),5).flat { .say } # |
| 139 | +
|
| 140 | +This is not really a syntactical "context" as much as it is a process of |
| 141 | +iteration, but it has the appearence of a context. |
| 142 | +
|
| 143 | +Note that L<C<Scalar>s|/type/Scalar> around a list will make it immune to |
| 144 | +flattening: |
| 145 | +
|
| 146 | + for (1,(2,$(3,4)),5).flat { .say } # says 1, then 2, then (3 4), then 5 |
| 147 | +
|
| 148 | +...but an C<@>-sigiled variable will spill its elements. |
| 149 | +
|
| 150 | + my @l := 2,(3,4); |
| 151 | + for (1, @l, 5).flat { .say }; # says 1, then 2, then 3, then 4, then 5 |
| 152 | + my @a = 2,(3,4); # Arrays are special, see below |
| 153 | + for (1, @a, 5).flat { .say }; # says 1, then 2, then (3 4), then 5 |
| 154 | +
|
| 155 | +=head2 Argument List (Capture) Context |
| 156 | +
|
| 157 | +When a list appears as arguments to a function or method call, special |
| 158 | +syntax rules are at play: the list immediately is converted into a |
| 159 | +C<Capture>. A C<Capture> itself has a List (C<.list>) and a Hash (C<.hash>). |
| 160 | +Any C<Pair> literals whose keys are not quoted, or which are not parenthesized, |
| 161 | +never make it into C<.list>. Instead, they are considered to be named |
| 162 | +arguments and squashed into C<.hash>. See the page on L<C<Capture>|types/Capture> |
| 163 | +for the details of this processing. |
| 164 | +
|
| 165 | +Consider the following ways to make a new C<Array> from a C<List>. These ways |
| 166 | +place the C<List> in an argument list context and because of that, the C<Array> |
| 167 | +only contains C<1> and C<2> but not the C<pair> C<:c3>, which is ignored. |
| 168 | +
|
| 169 | + Array.new(1, 2, :c(3); |
| 170 | + Array.new: 1, 2, :c(3); |
| 171 | + new Array: 1, 2, :c(3); |
| 172 | +
|
| 173 | +In contrast, these ways do not place the C<List> in argument list context, |
| 174 | +so all the elements, even the C<Pair> C<:c(3)>, are placed in the C<Array>. |
| 175 | +
|
| 176 | + Array.new((1, 2, :c(3)); |
| 177 | + (1, 2, :c(3)).Array; |
| 178 | + my @a = 1, 2, :c(3); Array.new(@a); |
| 179 | + my @a = 1, 2, :c(3); Array.new: @a; |
| 180 | + my @a = 1, 2, :c(3); new Array: @a; |
| 181 | + |
| 182 | +In argument list contet the C<|> prefix operator applied to a C<Positional> |
| 183 | +will always slip list elements as positional arguments to the Capture, |
| 184 | +while a C<|> prefix operator applied to an C<Associative> will slip pairs in |
| 185 | +as named parameters: |
| 186 | +
|
| 187 | + my @a := 2, "c" => 3; |
| 188 | + Array.new(1, |@a, 4); # Array contains 1, 2, :c(3), 4 |
| 189 | + my %a = "c" => 3; |
| 190 | + Array.new(1, |%a, 4); # Array contains 1, 4 |
| 191 | +
|
| 192 | +=head2 Array Constructor Context |
| 193 | +
|
| 194 | + [ 1, 2, :c(3) ] |
| 195 | +
|
| 196 | +=comment TODO actualy not sure if there is anything special here, other then the internal itemization best left for later -- eager maybe? |
| 197 | +
|
| 198 | +=head2 Slice Context |
| 199 | +
|
| 200 | + (1,2,3)[1, 2, :c(3)] |
| 201 | +
|
| 202 | +=comment TODO there is a typecheck against key/index, anything else? |
| 203 | +
|
| 204 | +=head1 Arrays |
| 205 | +
|
| 206 | +=head2 Itemization |
| 207 | +
|
| 208 | +=comment TODO explain nuances of automatic itemization done by arrays |
| 209 | +
|
| 210 | +=head2 Mutability |
| 211 | +
|
| 212 | +=head3 Binding |
| 213 | +
|
| 214 | +=head3 Assigning |
| 215 | +
|
| 216 | +=end pod |
0 commit comments