🎄 10/25. Reduction operator in Perl 6

Welcome to Day 10 of the Perl 6 One-Liner Advent Calendar! Today, there will be three one-liners instead of a regular one.

Our today’s guest is a reduction construction with a pair of square brackets. When they do not surround an array index, they work in a completely different field.

Example 1

The most classical example, which also got to the Perl 6 Calendar 2019, is using the reduction operator to calculate factorial:

say [*] 1..2019

[ ] in Perl 6 is a reduction meta-operator. The meta part of the name tells us that it can be used as an envelope for another operator (and not only operator, by the way).

In the first example, the operator includes another operator, and the whole line can be re-written by enrolling the range to a list and placing the * between all its elements:

say 1 * 2 * 3 #`(more elements) * 2018 * 2019

Example 2

Now, let us solve problem 5 of Project Euler, where we need to find the smallest number, which is dividable by all numbers from 1 to 20.

Let me show you a direct answer in Perl 6:

say [lcm] 1..20

This code looks very similar to the previous example, but uses another operator, the lcm routine, which is an infix operator in Perl 6. The name stands for least common multiplier, but in the documentation you can also read that it returns the smallest integer that is evenly divisible by both arguments. Almost the same words, which were used to formulate the problem we solve.

say 1 lcm 2 lcm 3 lcm 4 lcm 5 lcm 6 lcm 7 # ... and up to 20

Example 3

Other infix operators that are already built-in in Perl 6, can also be very productive. Here’s an example of rotating a matrix with just a few characters of code:

[Z] <A B C>, <D E F>, <H I J>

Here, we are transforming a two-dimentional matrix with nine elements, A through J. In the output, the rows become columns, and columns become rows:

((A D H) (B E I) (C F J))

The zip infix operator Z has been inserted between the elements of the list, and thus the code is similar to the following one:

<A B C> Z <D E F> Z <H I J>

Notice, that if you want to emphasise the order of operations, you might get not exactly what you wanted:

> (<A B C> Z <D E F>) Z <H I J>(((A D) H) ((B E) I) ((C F) J))

OK, before we did not go too far towards Lisp, let’s stop for today. See you tomorrow!