Welcome to the next issue of the series about the cool practical stuff in the Raku programming language. Today, we will discuss the usage of the so-called triangular reduction metaoperator.
Keeping preliminary results
Reduction operators are quite useful and allow to code the whole algorithm with just a few characters, as you do to compute a factorial, for example:
say [*] 1..5; # 120
Here, the computation is equivalent to 1 * 2 * 3 * 4 * 5
and only the result of it is returned.
But if you also want to get factorials of smaller numbers, or, in other words, to keep the intermediate results of enrolling the data and applying the operator, just add a backslach:
say [\*] 1..5; # (1 2 6 24 120)
The result is evaluated lazily, so we can have an array of factorials for any integer:
my @fact = [\*] 1..*; say @fact[^10]; # (1 2 6 24 120 720 5040 40320 362880 3628800) say @fact[20]; # 51090942171709440000
Rolling head of array
Let me demonstrate another interesting use case of the triangular metaoperator. This time, the main operator is ,
— the infix comma that makes the lists.
.say for [\,] ^5;
This program prints the following lines:
(0) (0 1) (0 1 2) (0 1 2 3) (0 1 2 3 4)
Tell me if you know the shorter way to get that.
For example, let’s compute the sums of the even integers below 10:
say [+] $_ for [\,] 2, 4 ...^ 10;
The program prints the values 2, 6, 12, 20, which are the sums of the following rows:
# 2 = 2 # 6 = 2 + 4 # 12 = 2 + 4 + 6 # 20 = 2 + 4 + 6 + 8
* * *
Find the code of this issue on GitHub and browse for more Raku Pearls.
Thank you. I’m learning a lot from your posts. Noticed an error on this one… the prefix ^ is the “up to” operator. So
.say for [\,] ^5;
will result in one less line that the output you mention:
$ raku -e ‘.say for [\,] ^5;’
(0)
(0 1)
(0 1 2)
(0 1 2 3)
(0 1 2 3 4)
Thanks, you are so right!