🎄 9/25. More on X, .., and … in Perl 6

Welcome to Day 9 of the Perl 6 One-Liner Advent Calendar! On Day 6, we had a construct with a cross-operator, (999...100) X* (999...100). Today, we’ll dive into a similar construction from November:

1..10 X* 1..10

It prints the items of the product table for the numbers from 1 to 10:

(1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100)

There are a few things to learn about such constructions.

You may have noticed two subtle differences between 999...100 and 1..10. In one case, there are three dots, in another—only two. In the first case, the boundaries are decreasing numbers, in the second—increasing.

Two dots in Perl 6 is the range operator. It creates a Range, or, in other words, an object of the Range type.

Three dots in Perl 6 are the sequence operator. In our example, it creates a sequence, or an object of the Seq type.

You can always check the type by calling the WHAT method on the object (a fragment of the REPL session is shown below):

> (1..10).WHAT
(Range)
> (1...10).WHAT
(Seq)

It is also interesting to look into the source codes of Rakudo, and see which attributes the Range and Seq have.

my class Range is Cool does Iterable does Positional {
has $.min;
has $.max;
has int $!excludes-min;
has int $!excludes-max;
has int $!infinite;
has int $!is-int;
. . .
}
my class Seq is Cool does Iterable does Sequence {
has Iterator $!iter;
. . .
}

In the Range object, there are minimum and maximum values, while in Seq we see an iterator.

In some cases, for example, in a simple loop, you can choose between either a range or a sequence:

.say for 1..10;
.say for 1...10;

But if you want to count downwards, ranges will not work:

> .say for 10..1;
Nil

With a sequence, there’s no problem:

> .print for 10...1;
10987654321>

It is wise to play with ranges and sequences before you start feeling them well. Save them in variables, use in operations, print using say or dd.

As a starting point, consider three operations:

(1, 2, 3) X* (4, 5, 6);
(1..3) X* (4..6);
(1...3) X* (4...6);

And that’s what you can be doing until tomorrow’s Advent post!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s