Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #2775 from taboege/subscript-range-whatever
Fix infinite range subscript examples
  • Loading branch information
JJ committed May 10, 2019
2 parents b2a4977 + 57641d1 commit 1f8e0da
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
27 changes: 22 additions & 5 deletions doc/Language/list.pod6
Expand Up @@ -477,18 +477,35 @@ which is selecting the 4 to 6th element from the three first dimensions (C<^3>)
=head2 Range as slice
A L<C<Range>|/type/Range> is a container for a lower and an upper boundary.
Generating a slice with a C<Range> will include any index between those bounds,
including the bounds. For infinite upper boundaries we agree with
mathematicians that C<Inf> equals C<Inf-1>.
A L<C<Range>|/type/Range> is a container for a lower and an upper boundary,
either of which may be excluded. Generating a slice with a C<Range> will
include any index between the bounds, though an infinite Range will
L<truncate|/language/subscripts#Truncating_slices> non-existent elements.
An infinite range with excluded upper boundary (e.g. C<0..^Inf>) is still
infinite and will reach all elements.
my @a = 1..5;
say @a[0..2]; # OUTPUT: «(1 2 3)␤»
say @a[0..^2]; # OUTPUT: «(1 2)␤»
say @a[0..*]; # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..^*]; # OUTPUT: «(1 2 3 4)␤»
say @a[0..^*]; # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..Inf-1]; # OUTPUT: «(1 2 3 4 5)␤»
Note that when the upper boundary is a WhateverCode instead of just a Whatever,
the range is not infinite but becomes a Callable producing Ranges. This is
normal behavior of the L<..|/type/Range> operator. The subscript operator
L<[]|/language/subscripts#Slices> evaluates the WhateverCode providing the
list's C<.elems> as an argument and uses the resulting range to slice:
=for code :preamble<my @a = 1..5>
say @a[0..*-1]; # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..^*-1]; # OUTPUT: «(1 2 3 4)␤»
# Produces 0..^2.5 as the slice range
say @a[0..^*/2]; # OUTPUT: «(1 2 3)␤»
Notice that C<0..^*> and C<0..^*+0> behave consistently in subscripts despite
one being an infinite range and the other a WhateverCode producing ranges.
=head2 Array constructor context
Inside an Array Literal, the list of initialization values is not in capture
Expand Down
2 changes: 2 additions & 0 deletions doc/Language/subscripts.pod6
Expand Up @@ -225,6 +225,8 @@ In particular the I<type> can be any of the following:
=item a lazy Iterable, that L<truncates|#Truncating slices> in [ ]
=item accordingly, an infinite Range will truncate, but a finite one produces a normal slice
=item '*' (whatever-star), that returns the full slice (as if all keys/indices were specified)
=item any other object, that provides a single-element access rather than a slice
Expand Down
12 changes: 12 additions & 0 deletions doc/Type/Range.pod6
Expand Up @@ -48,6 +48,18 @@ Use C<∞> or C<*> (Whatever) to indicate an end point to be open-ended.
for 1..* { .say }; # start from 1, continue until stopped
for 1..∞ { .say }; # the same
Beware that a L<WhateverCode|/type/WhateverCode> end point, instead of a plain
Whatever, will go through the range operator and create another WhateverCode
which returns a Range:
=for code
# A Whatever produces the 1..Inf range
say (1..*).WHAT; # OUTPUT: «(Range)␤»
say (1..*); # OUTPUT: «1..Inf␤»
# Upper end point is now a WhateverCode
say (1..*+20).WHAT; # OUTPUT: «(WhateverCode)␤»
say (1..*+20).(22); # OUTPUT: «1..42␤»
Ranges implement L<Positional|/type/Positional> interface, so its elements can
be accessed using an index. In a case when the index given is bigger than the
Range object's size, L<Nil|/type/Nil> object will be returned. The access works
Expand Down

0 comments on commit 1f8e0da

Please sign in to comment.