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:

    $prod = [*] @a;           # multiply all elements of @a

    $mean = ([+] @a) / @a;    # calculate mean of @a

    $sorted = [<=] @a;        # true if elements of @a are numerically sorted

    $min = [min] @a, @b;      # find the smallest element of @a and @b combined

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

    # each element of @x is the smaller of @a and @b
    @x = @a »min« @b;

We can also flip the angles to enable a scalar to act like an array:

    # multiply each element of @a by 3.5
    @b = @a »*» 3.5;

    # multiply each element of @x by $m and add $b
    @y = @x »*» $m »+» $b;

    # invert all elements of @x
    @inv = 1 «/« @x;

    # concatenate @last, @first to produce @full
    @full = (@last »~» ', ') »~« @first;

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:

    $a += 5;      # same as $a = $a + 5;
    $b //= 7;     # same as $b = $b // 7;
    $c min= $d;   # same as $c = $c min $d;

Tags: ,

14 Responses to “Day 5: Metaoperators”

  1. Perl 6 Advent Calendar « Perl 6 Advent Calendar Says:

    […] Day 1: Getting Rakudo Day 2: The Beauty Of Formatting Day 3: Static Types and Multi Subs Day 4: Testing Day 5: Metaoperators […]

  2. ragnar Says:

    $c min= $d; is one of the most awesome things i’ve seen since … i last learned something new about perl6!
    thank you

  3. bened Says:

    Wow, this is very impressive! Can’t wait to use this in real world applications!

  4. Day 6: Going Into Hyperspace « Perl 6 Advent Calendar Says:

    […] Perl 6 Advent Calendar Something cool about Perl 6 every day « Day 5: Metaoperators […]

  5. RonW Says:

    Very impressive, but I can’t help thinking about “APL”. Will we soon need special keyboards to code in Perl?

    (And yes, APL did have bi- and tri-graphs for all its special characters, but that made for a lot of extra typing)

  6. jmo Says:

    Wow, just like APL but 50 years later!

    in APL direct definition:

    fac: */ιω

    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.

  7. Perl 6 looks quite good « Says:

    […] had a chance to look at the perl 6 advent calendar. What caught my eye was yesterdays post. In it, meta operators are […]

  8. John B Says:

    The influence of LISP continues… “meta operators”

  9. Perl 6 Advent Calendar на русском | Ky6uk's Blog Says:

    […] Perl 6 Advent Calendar на русском 8 Декабрь 2009 Ky6uk Написать комментарий К комментариям Разработчики проекта Rakudo, реализации языка Perl 6 на базе виртуальной машины Parrot, объявили о проведении предрождественского марафона, в рамках которого с 1 по 26 декабря в блоге каждый день будут публиковаться практические уроки, демонстрирующие те или иные возможности Perl 6. В первую неделю декабря в рамках цикла статей было рассказано обустановке Rakudo, использованию циклов, операторах форматирования,статических типах,  […]

  10. Deriksims Says:

    Да уж. По поводу коментариев – навеяла на меня где-то услышанная фраза:
    Только наш клиент в графе “Телефон” мог написать Samsung.

  11. Игорь Says:

    Дискутировать можно бесконечно, поэтому просто поблагодарю автора. Спасибо!

  12. День 6: Входя в Гиперпространство | Ky6uk's Blog Says:

    […] Perl 6 Advent Calendar на русский язык. Вчера pmichaud предствавил гипероператоры Perl 6 (рус.). Я хотел бы продолжить обзор этих мощных […]

  13. The Perl 6 Advent Calendar | JetLib News Says:

    […] 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 […]

  14. 扶凯 » [Perl6]reduce 和 hyper 元操作符 Says:

    […] 本文为译文原作者 By pmichaud: […]

Leave a Reply

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

You are commenting using your 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 )

Google+ photo

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

Connecting to %s


Get every new post delivered to your Inbox.

Join 50 other followers

%d bloggers like this: