Centenary Sequences with Raku
Part 1

by Arne Sommer

# Centenary Sequences with Raku - Part 1: Raku

[100.1] Published 4. November 2020.

## Range vs Sequence

Raku has two built in types we can use to generate sequences:

• Range: Consecutive increasing integers only, generated with the `..` operator.
• Sequence: Numeric values in any form and/or order, generated with the `...` 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.

## Usage

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 `^`.

## Lazy Data Structures

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.

## put vs say

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 ```