Еще в 1748 году М. В. Ломоносов открыл закон сохранения магии. Или все-таки вещества? - да какая разница! Этот закон гласит: "Так, ежели где убудет несколько магии, то умножится в другом месте".
В соответствии с законом сохранения магии в Perl6, когда многие вещи стали простыми, появились очень интересные новые возможности. Среди нововведений - гипероператоры, reduction и cross операторы. Это операторы предназначены для работы со списками. Кстати, подобные им операторы изначально имеются в магических языках семейства APL.
Наличие таких нововведений в Perl6 позволяет выражать мысли более компактно и ясно. Рассмотрим некоторые примеры и сравним их с примерами на языке J (http://jsoftware.com), который является потомком языка APL. Для простоты в нижеприведенных примерах код обозначен отступом вправо, а результат работы - отступом влево.
Примеры выполнены при помощи Rakudo (компилятор Perl 6, основанный на Parrot) Rakudo - сокращение от японского Rakuda-do, что означает "Путь верблюда".
Перед основыми примерами создаем списки (массивы, вектора):
Perl | J
------------------------------------------------
@x = (1 .. 3) | x=. 1 2 3
@y = (4 .. 6) | y=. 4 5 6
В J списки создаем вручную, чтобы не забегать вперед.
Гипероператоры
Гипероператоры производят операции над списками поэлементно. Смотрите http://perlcabal.org/syn/S03.html#Hyper_operators. Сложение двух списков при помощи гипероператора и прибавление к списку числа:
Perl | J
------------------------------------------------
@x >>+<< @y | x + y
5, 7, 9 | 5 7 9
@x >>+>> 3 | x + 3
4, 5, 6 | 4 5 6
В J оператор является аналогом Perl гипероператора, что не удивительно, ведь APL - язык векторных вычислений.
Reduction операторы
Эти операторы работают не с единичными элементами списка, а с учетом результата действий над предыдущими элементами. http://perlcabal.org/syn/S03.html#Reduction_operators
Perl | J
------------------------------------------------
[+] @x | +/ x
6 | 6
Для достижения аналогичного результата в J оператор модифицируется наречием "поэлементно".
Следующий пример еще не работает в Rakudo (parrot revision 35576). Отличие этого примера от предыдущего в том, что сумма считаеться не для всего списка, а для каждой его части:
Perl | J
------------------------------------------------
[\+] @x | +/\ x
1, 3, 6 | 1 3 6
В J это делается при помощи наречия "префиксно".
Cross операторы
Эти операторы производят действие над каждой комбинацией элементов списков.
http://perlcabal.org/syn/S03.html#Cross_operators
Сделаем фрагмент таблицы умножения:
Perl | J
------------------------------------------------
@x X*X @y | x */ y
4, 5, 6, 8, 10, 12, 12, 15, 18 | 4 5 6
| 8 10 12
| 12 15 18
В J оператор модифицируется наречием "таблично". Отличие Perl от J в том, что в J сразу создается матрица, а Perl придется список преобразовать в таблицу. Просто у Perl и J разное распределение магии.
Выводы
Как видим, Perl получил в свой арсенал мощные возможности для работы со списками, Нельзя сказать, что они соизмеримы с возможностями векторных языков, но их вполне хватает для "бытовых" нужд.
Для "профессиональных" векторных вычислений рекомендуется использовать Perl Data Language (http://pdl.perl.org).
Комментариев нет:
Отправить комментарий