See also: The Introduction.
Raku has two built in types we can use to generate sequences:
..
operator.
...
operator.
Note that both the ..
and the ...
operators are binary.
They take two parameters, one on each side of the operator:
> say (1 .. 10); # -> (1 2 3 4 5 6 7 8 9 10)
> say (1 ... 10); # -> (1 2 3 4 5 6 7 8 9 10)
Raku Ranges and Sequences can be of infinite length:
> say (0 .. Inf)[^10]; # -> (0 1 2 3 4 5 6 7 8 9)
A Range cannot count down, but a Sequence can:
> say (0 .. -Inf)[^10]; # -> (Nil Nil Nil Nil Nil Nil Nil Nil Nil Nil)
> say (0 ... -Inf)[^10]; # -> (0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
See
docs.raku.org/type/Range
for more information about the Range
type.
See
docs.raku.org/type/Sequence
for more information about the Sequence
type.
The simplest use case is a loop that should be run a specific number of times.
The traditional method is the C-style loop, which is available as
loop
in Raku:
loop (my $i=1; $i <= 10; $i++) { say $i }
This will print the numbers 1 to 10, each on its own line.
We can use a Range instead, in combination with the Raku for
iterator
like this:
for 1 .. 10 -> $i { say $i }
If we are only interested in the number of iterations,
the Range Upto Operator ^
is pretty neat:
for ^10 -> $i { say $i } # The same as (0 .. 9)
As long as you are OK with the numbers starting at zero, and ending one below the given upto limit.
See
docs.raku.org/syntax/loop
for more information about the loop
keyword.
See
docs.raku.org/routine/^
for more information about the Upto Operator ^
.
Infinite data structures, as shown above with infinity as the upper limit, are fine as we get a lazy data structure - where the values are only computed when actually used).
Printing a lazy data structure does not give us any values:
say (1 .. Inf); # -> 1..Inf
put (1 .. Inf); # -> 1..*
Note the alternate symbol for infinity:
*
, used by put
. You can use whichever you want,
*
, Inf
- or even the Unicode ∞
symbol (U+221E).
We can print the first 10 values of an infinite Range like this:
say (1 .. Inf)[^10]; # -> (1 2 3 4 5 6 7 8 9 10)
put (1 .. Inf)[^10]; # -> 1 2 3 4 5 6 7 8 9 10
You can ask Raku if the data structure is lazy, with the
is-lazy
method if you are in doubt:
say (1 .. Inf).is-lazy; # -> True
say (1 .. Inf)[^10].is-lazy; # -> False
See
docs.raku.org/routine/is-lazy
for more information about the is-lazy
method.
Note that say
will not always print what we give it, but
put
will:
> say (1 .. Inf)[^110];
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 \
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 \
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 \
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 ...)
> put (1 .. Inf)[^110];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 \
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 \
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 \
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 \
103 104 105 106 107 108 109 110