Главная > Perl > День 6: Входя в Гиперпространство

День 6: Входя в Гиперпространство

Вольный перевод шестой статьи цикла Perl 6 Advent Calendar на русский язык.

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

Во-первых, я буду использовать вспомогательную функцию lsay для упрощения и красивого вывода списков.

sub lsay(@a) { @a.perl.say }

Теперь мы можем начать рассматривать примеры гипероператоров. В этой заметке я буду использовать >> и << вместо » и «, в основном потому, что они легче для моих глаз. (Я боюсь, что потребуется взять очки.) » и «, как правило, считаются истинной записью оператора, но ASCII-версия так же будет работать.

Для начала основы: складываем два списка одинаковой длины:

> lsay (1, 2, 3, 4) <<+>> (3, 1, 3, 1)
[4, 3, 6, 5]
> lsay (1, 2, 3, 4) >>+<< (3, 1, 3, 1)
[4, 3, 6, 5]

При одинаковой длине массивов нет никакой разницы между этими формами. Но если длина различна:

> lsay (1, 2, 3, 4) <<+>> (3, 1)
[4, 3, 4, 5]
> lsay (1, 2, 3, 4) >>+<< (3, 1)
Non-dwimmy hyperoperator cannot be used on arrays of different sizes or dimensions.

Как правило, список, на который указывает гипероператор "острым" концом, может быть расширен если он короче чем другой; он расширяется повторением последнего элемента этого списка. В тоже время список, на который указывает "тупой" конец гипероператора, не может быть расширен. Все комбинации разрешены, поэтому вы можете указать на то, что расширена может быть только левая сторона (<<+<<), только правая (>>+>>), обе стороны могут быть расширены (<<+>>), или ни одна из сторон не может быть расширена (>>+<<). Одиночные скаляры так же расширяемы:

> lsay (1, 2, 3, 4) >>+>> 2
[3, 4, 5, 6]
> lsay 3 <<+<< (1, 2, 3, 4)
[4, 5, 6, 7]

В основном, гипероператоры используются с инфиксными операторам. Теоретически, вы так же можете использовать их с префиксными или постфиксными операторами:

> lsay ~<<(1, 2, 3, 4)
["1", "2", "3", "4"]
> lsay (1, 2, 3, 4)>>++
[2, 3, 4, 5]

На практике такое использование не было осуществлено в Rakudo, за исключением одного особого случая:

> lsay (0, pi/4, pi/2, pi, 2*pi)>>.sin
[0, 0.707106781186547, 1, 1.22464679914735e-16, -2.44929359829471e-16]
> lsay (-1, 0, 3, 42)>>.Str
["-1", "0", "3", "42"]

То есть >>. вызывает метод Str на каждом элементе списка.

Насколько бы вам не хотелось написать @array>>.say, не делайте этого. Это может работать в текущей версии Rakudo, но при использовании гипероператоров вы обещаете что операция параллелизуема, и порядок операций на списке(-ах) не фиксирован. Надеюсь, что в будущих версиях Perl 6 эти операции будут выполняться параллельно.

Другие примечания: Гипероператоры работают не только со встроенными операторами. Они будут работать с любым новым оператором который вы определите. (В основном, сейчас это уже работает в Rakudo.) Гипероператоры будут работать с in-place операторами, напрмиер @a >>/=>> 2 разделит весь массив на 2. (Это не работает в текущей версии Rakudo.) Они будут работать с многомерными списками, с деревьями и с хэшами; смотрите S03 Hyper operators. (Насколько я знаю, они еще не работают в Rakudo.)

Я больше не знаю примеров использования, но область применения гипероператоров достаточно широка. Например класс Vector написанный LastOfTheCarelessMen довольно неплох — это реализация N-мерного вектора без единой явной петли.

© Оригинальная статья.

VN:F [1.9.13_1145]
Rating: 7.0/10 (2 votes cast)
День 6: Входя в Гиперпространство, 7.0 out of 10 based on 2 ratings
Categories: Perl Tags: ,
  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.