Day 5: Metaoperators

In the Day 4 box, we saw an interesting implementation for the factorial function:

sub fac(Int $n) {
[*] 1..$n
}

Okay, so how does that work? Opening up today’s Advent box provides some answers!

Perl 6 has a number of different “meta operators” that modify the existing operators to perform more powerful functions.

The square brackets about are an example of the “reduce metaoperator”; they cause an infix operator to become a list operator that acts as though the infix was placed between each pair of elements. For example, the expression

[+] 1, $a, 5, $b

is essentially the same as writing

1 + $a + 5 + $b

This gives us a handy mechanism to “sum all elements in a list”:

$sum = [+] @a; # sum all elements of @a

Most of the infix operators (including user-defined operators) can be placed inside of square brackets to turn them into reductions:

So, in the factorial subroutine above, the expression [*] 1..$n returns the product of multiplying all of 1 through $n together.

Another useful metaoperator is the “hyper” operator. Placing »
and/or « (or the ASCII >> and << equivalents) next to an operator makes it “hyper”, which causes it operate on elements of lists. For example, the following calculates @c as the pairwise addition of the elements in @a and @b:

@c = @a »+« @b;

In Perl 5, we’d generally write something like

for ($i = 0; $i < @a; $i++) {
$c[$i] = $a[$i] + $b[$i];
}

which is quite a bit longer.

As with the square brackets above, we can use hyper on a variety of operators, including user-defined operators:

# increment all elements of @xyz
@xyz»++
# each element of @x is the smaller of @a and @b
@x = @a »min« @b;

Of course, reductions and hyper operators can be combined in expressions:

# calculate the sum of squares of @x
$sumsq = [+] ( @x »**» 2);

There are many other metaoperators available, including X (cross), R (reverse), S (sequential). In fact, the “in-place” operators such as +=, *=, ~=, are just meta forms created by suffixing an operator with an equals sign:

Like this:

Related

This entry was posted on December 5, 2009 at 12:01 am and is filed under 2009. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

where ω is a the argument of the “fac” function, and “/” is the reduction operator. As for the “hyper” operator, this was the default operator for scalar functions in APL – it was never explicit. You could write “A + B” and if A and B were conformal arrays, the result was a conformal array where each element was the result of adding each corresponding element of A and B.

[…] and build Rakudo (the most actively developed and progressed implementation of Perl 6) and the new Metaoperators. For those wondering when Perl 6 will be finished: Rakudo will be having its official […]