Raku

(перенаправлено с «Perl 6»)

Raku (от яп. 楽土произн. ракудо — Рай,[1][2] и от , произн. раку — счастье, лёгкость, сукха[3][4]) — язык программирования из семейства Perl-подобных языков. Серьёзный пересмотр как дизайна, так и реализации языка Perl, нарушающий обратную совместимость с ним, хотя до 2010 года еще предполагалось наличие режима совместимости.[5]

Raku (ранее Perl 6)
Класс языка Мультипарадигмальный
Появился в Разработка ведётся с 2000 года. Первый релиз состоялся 25 декабря 2015 года
Автор Ларри Уолл
Разработчик Ларри Уолл и Одри Тан
Расширение файлов .raku, .rakumod, .rakudoc, .rakutest или .t
Выпуск 6.d (24 февраля 2020; 4 года назад (2020-02-24))
Система типов динамическая, статическая
Испытал влияние
Повлиял на Perl, Haskell, AntLang
Лицензия GNU General Public License, Artistic License
Сайт raku.org
ОС кроссплатформенность

Подобно языку Perl, Raku оставляет программистам много свободы. Он всё еще позволяет выражаться кратко, в том числе писать однострочники, но также упрощает и написание больших программ, благодаря статической типизации и улучшенной поддержке ООП.

Прежнее название Raku — Perl 6.[6] В течение многих лет в сообществе Perl имели место шуточные замечания о дате релиза. На вопрос «когда выйдет Perl 6» обычным ответом было «на Рождество», но без указания года.[7][8] В 2015 году, то есть после пятнадцати лет ожидания, наконец была анонсирована так называемая «рождественская» версия.[9][10][11]

История править

В Perl 6 мы решили, что лучше исправить язык, чем исправлять пользователя.Ларри Уолл[12]

Разработка Perl 6 была впервые анонсирована Ларри Уоллом 19 июля 2000 года, в четвертый день Perl Conference того года,[13] в его выступлении State of the Onion.[14] В то время первоочередными задачами было: удалить из языка «исторические бородавки»; «простые вещи должны оставаться простыми, сложные вещи должны становиться проще, и невозможные вещи должны стать сложными»; общая чистка внутреннего дизайна и API. Процесс начался с серии RFC. Этот процесс был открыт для всех участников, и ни один аспект языка не оставался закрытым для изменений.[15]

Был получен 361 запрос, каждый из которых был рассмотрен Уоллом. Затем он начал процесс написания нескольких «Апокалипсисов» — христианский термин, означающий «раскрытие хороших новостей хорошим людям».[16] Хотя первоначальной целью было написать по одному Апокалипсису для каждой главы книги en:Programming Perl, стало очевидно, что по мере написания каждого Апокалипсиса, предыдущие Апокалипсисы аннулировались более поздними изменениями. По этой причине был опубликован набор Синопсисов, каждый из которых относился к одному Апокалипсису, но включал корректировки из новых Апокалипсисов. Сегодня спецификация Raku управляется набором тестов «roast»,[17] в то время как Синопсисы хранятся в качестве исторической справки.[18]

Есть также серия Экзегез, написанных Дэмиэном Конуэем, которые объясняют содержание каждого Апокалипсиса с точки зрения практического использования. Каждая Экзегеза состоит из примеров кода с обсуждением их использования и значения.[19]

Первоначальные цели и последствия править

Основной целью, которую Уолл предложил в своей первоначальной речи, было удаление «исторических бородавок». К ним относилась путаница в сигилах массивов и хэшей, неоднозначность функций select, проблемы с использованием голых[20] (без пунктуации[21]) файловых дескрипторов. Уолл также упомянул в своей речи много других проблем, решение которых Perl-программисты обсуждали годами.[источник не указан 986 дней]

Последствием этих целей стала потеря обратной совместимости. Поскольку обратная совместимость обычно подразумевается при улучшении программного обеспечения, ломающие её изменения в Perl 6 должны были быть явно сформулированы. Постепенно различие между Perl 5 и Perl 6 стало настолько большим, что 12 октября 2019 года Perl 6 был переименован в Raku.[6]

За прошедшие годы вектор развития Raku менялся несколько раз. Введение концепций из Python и Ruby было ранним влиянием.[22][23][24] Кроме того, Pugs, первый интерпретатор Raku, написан на функциональном языке Haskell, и многие элементы функционального программирования были впитаны командой разработчиков Raku.[25][26]

Маскот править

 
Ларри Уолл на фоне бабочки Камелии — талисмана Perl 6

Маскот языка — насекомое Камелия.[27] Его имя — отсылка к эмблеме языка Perl, верблюду («Camel»), а его форма, в традициях любящего каламбуры сообщества Perl, перекликается со словом «bug». Спиральные узоры, вписанные в его крылья, похожие на крылья бабочки, напоминают символы «P6», а расходящееся косоглазие — это преднамеренный каламбур с выражением «Wall-eyed».[28]

Одна из целей живого и красочного дизайна логотипа заключалась в том, чтобы препятствовать мизогинии в сообществе и дать возможность людям с «мужскими убеждениями» показать свою чувствительную сторону.[29]

Реализации править

Rakudo — наиболее развитая реализация,[30] что не делает её официальной версией языка, т.к. язык определяется не реализацией, а набором тестов.[31]

Rakudo позволяет выполнять[32] код в виртуальных машинах MoarVM, JVM и на платформе Node.js.[33] MoarVM — виртуальная машина, созданная специально для Rakudo и компилятора NQP.[34][35] Компилятор NQP (Not Quite Perl 6, с англ. — «не совсем Perl 6») реализует подмножество языка, включающее правила Raku для разбора исходного кода, работы с абстрактным синтаксическим деревом и бэкенд-специфичной кодогенерацией. Значительная часть Rakudo написана на Raku и NQP. Rakudo — не самодостаточный компилятор, и в данный момент раскрутка компилятора не планируется.

После версии «2015.02», в Rakudo была прекращена поддержка виртуальной машины Parrot[36] (предшественницы MoarVM), создающейся исходя из ошибочного предположения, что Perl 6 будет похож на Perl 5.[37][38]

Исторические реализации править

Первой реализацией Raku был Pugs[39] — интерпретатор и компилятор, написанный на Haskell. Был самой продвинутой реализацией, однако с 2007 года вносились только минимальные исправления для соответствия новым версиям GHC, и по состоянию на ноябрь 2014 года Pugs не поддерживается.[40] В августе 2006 года Yichun Zhang разбил файлы тестов Pugs на фрагменты, прикрепив к ним соответствующие параграфы Синапсисов,[41][42] а в январе 2008 года эти тесты были интегрированы в официальные тесты языка («roast»).[43][44] В феврале 2015 года сообщество объявило тесты языка его спецификацией.[45]

  • «Niecza» — компилятор из Perl 6 в байт-код виртуальной машины «Common Language Runtime» (CLR);
  • «Yapsi» — компилятор, написанный на языке Perl 6 реализации «Rakudo».

Основные отличия от Perl править

Raku и Perl отличаются фундаментально, хоть в основном и было намерение оставить Raku Perl'овым. Большая часть изменений предназначена для нормализации языка, чтобы его было легче понять как новичкам, так и опытным программистам, и сделать «простые вещи проще, а сложные — более возможными».

Спецификация править

Основное нетехническое различие заключается в том, что Raku начинался как спецификация.[31] Это значит, что при необходимости Raku может быть повторно реализован, а также, что программистам не нужно читать исходный код, чтобы получить полный контроль над любой его возможностью. В случае же языка Perl, официальная документация только описывает поведение текущего интерпретатора. Любые расхождения, обнаруженные между документацией и реализацией, могут привести к тому, что либо одно, либо другое будет изменено, что является движущей силой постоянной разработки и совершенствования выпусков Perl.

Система типов править

В Raku динамическая система типов была дополнена статическими типами.[46] Например:

my Int $i = 0;
my Rat $r = 3.142;
my Str $s = "Hello, world";

Однако, статические типы остаются опциональными, так что программисты могут делать большую часть вещей без явного указания типов.

my $i = "25" + 10; # $i is 35

Список формальных параметров подпрограмм править

В Perl у подпрограмм нет формальных параметров, хоть простая проверка количества и типов параметров возможна с помощью прототипов подпрограмм.[47] Вместо этого, фактические параметры, передаваемые по ссылке, прячутся за элементами массива @_ в теле подпрограммы.

В Raku появляются настоящие формальные параметры.[48] Например:

sub do_something(Str $thing, Int $other) {
    ...
}

Также, как в языке Perl, в Raku параметры передаются по ссылке, но по умолчанию в Raku они константны, т.е. значения в них не могут быть изменены. Они могут быть явно объявлены как позволяющие менять оригинальное значение (is rw) или как копии (is copy), что эквивалентно передаче по значению.

Способы передачи параметров править

В Raku три способа передавать параметры: позиционный, именованный и хлюпающий (slurpy).

Позиционные параметры — это обычный упорядоченный список, как в большинстве языков программирования. Даже они могут быть переданы в произвольном порядке, если указывать их имена. Параметры же, которые могут быть переданы только по имени, обозначаются символом : перед сигилом формального параметра. Хлюпающие параметры — это способ создавать вариативные функции в Raku. Они обозначаются символом * перед сигилом формального параметра. Slurpy-хэш будет захватывать неупомянутые при объявлении подпрограммы именованные параметры, а slurpy-массив — последующие позиционные фактические параметры.

В следующем примере присутствуют все три способа, включая slurpy-массив.

sub somefunction($a, $b, :$c, :$d, *@e) {
    ...
}

somefunction(1, 2, :d(3), 4, 5, 6); # $a=1, $b=2, $d=3, @e=(4,5,6)

Позиционные параметры по умолчанию обязательны, если только после имени параметра не стоит вопросительный знак. Именованные же параметры по умолчанию наоборот опциональны, если только после имени не стоит восклицательный знак. Хлюпающие параметры опциональны всегда.

Блоки и замыкания править

Параметры также могут быть переданы в любые блоки кода, которые ведут себя как замыкания. В частности, например, тела циклов for и while являются замыканиями. В следующем примере цикл берёт из списка по три элемента за раз и передаёт их в блок как переменные $a, $b и $c.[49]

for @list -> $a, $b, $c {
    ...
}

Это называется «pointy sub» или «pointy block», и стрелка в нём ведёт себя примерно как ключевое слово sub, вводя анонимное замыкание (или анонимную подпрограмму в терминологии Perl).[48]

Инвариантность сигилов править

В Perl, сигилы (знаки пунктуации, находящиеся перед именами переменных) меняются в зависимости от вида использования переменной.

# Perl-код
my @array = ('a', 'b', 'c');
my $element = $array[1];    # возвращает 'b',
my @extract = @array[1, 2]; # возвращает ('b', 'c')
my $element = @array[1];    # возвращает 'b' с предупреждением (с версии 5.10)

В Raku же сигилы инвариантны: как у массива, так и у элемента массива будет один и тот же сигил.[46]

# Raku-код
my @array = 'a', 'b', 'c';
my $element = @array[1];    # в $element записывается 'b'
my @extract = @array[1];    # в @extract записывается ('b')
my @extract = @array[1, 2]; # в @extract записывается ('b', 'c')

Изменчивость сигилов в Perl вдохновлена согласованием числа в английском и многих других естественных языках.

"Это яблоко."                    # $a        верно
"Эти яблоки."                    # @a        верно
"Это третье яблоко."             # $a[3]     верно
"Эти третье яблоко."             # @a[3]     не верно

Однако эта концепция нарушается, когда в игру вступают ссылки, поскольку они могут относиться к структурам данных, являясь в то же время скалярами. Таким образом, работа с вложенными структурами данных может потребовать выражения как единственного, так и множественного числа в одном термине:

# Perl-код: получение массива из элемента хэша.
# В этом хэше хранятся хэши, содержащие массивы.
my @trans_verbs = @{ $dictionary{ 'verb' }{ 'transitive' } };

Подобные конструкции не имеют аналогов в распространённых естественных языках, что вызывает высокую когнитивную нагрузку при написании кода. Тот же код на языке Raku:

# Raku-код: получение массива из элемента хэша.
# В этом хэше хранятся хэши, содержащие массивы.
my @trans_verbs = %dictionary<verb><transitive><>;

Объектно-ориентированное программирование править

В языке Perl объектно-ориентированное программирование поддерживается через функцию bless, превращающую любую переменную в объект определенного класса, у которого становятся доступными для вызова методы, объявленные в классе.[50]

Будучи чрезвычайно мощным, этот механизм в то же время делает трудным описание даже самого базового ООП — простых структуро-подобных объектов со связанными процедурами. Кроме того, поскольку Perl не делает никаких предположений об объектной модели, вызов методов не может быть оптимизирован компилятором.

Raku оставляет низкоуровневый метод bless, но также предоставляет более жестко огранивающую объектную модель для распространенных случаев.[51][52] Например, класс, инкапсулирующий точку в декартовой системе координат, может быть определён следующим образом:

class Point is rw {
    has $.x;
    has $.y;
    
    method distance( Point $p ) {
        sqrt(($!x - $p.x) ** 2 + ($!y - $p.y) ** 2)
    }
    
    method distance-to-center {
        self.distance: Point.new(x => 0, y => 0)
    }
}

my $point = Point.new( x => 1.2, y => -3.7 );
say "Позиция точки: (", $point.x, ', ', $point.y, ')';
# Позиция точки: (1.2, -3.7)

# Изменение x и y (используются методы "x" и "y"):
$point.x = 3;
$point.y = 4;
say "Позиция точки: (", $point.x, ', ', $point.y, ')';
# Позиция точки: (3, 4)

my $other-point = Point.new(x => -5, y => 10);
$point.distance($other-point); #=> 10
$point.distance-to-center;     #=> 5

В Perl методы вызываются с помощью стрелки: $object->method(). В Raku вместо стрелки используется точка, как во многих других языках (например, Java и Python).

В терминологии Raku $.x называется атрибутом. Метод, используемый для доступа к атрибуту называется аксессором[53] (от англ. access — доступ). Он создаётся автоматически (при объявлении атрибута через точку[54]) и называется так же, как атрибут. Он работает как геттер и, когда класс или атрибут is rw, приобретает свойства сеттера и может использоваться в левой части присваивания. Вместо автоматических аксессоров, программист может определить свои нестандартные методы. Также, в теле класса ко всем атрибутам, вне зависимости от того, как они объявлены, можно обратиться напрямую, используя синтаксис $!.

Наследование, роли и классы править

Наследование — это техника, при которой объекты или типы переиспользуют логику или определения из других объектов или типов. Например, программист может сделать стандартный тип с дополнительным атрибутом. В таких языках, как Java, наследование обеспечивается классами, которые могут быть подклассами других существующих классов.

Raku тоже предоставляет наследование c помощью классов, подобных классам в других языках программирования, а также c помощью ролей.

Роли в Raku берут на себя функцию интерфейсов в Java, примесей в Ruby, трейтов[55] в PHP и Squeak (диалекте языка Smalltalk). Они похожи на классы, но обеспечивают более безопасный, чем наследование, механизм композиции, предотвращающий конфликты имён атрибутов и методов.[56][57] Роли не встраиваются в цепочку наследования. Роли относятся к номинальной системе типов (см. en:Nominal type system), а не структурной, которая применяется, например, в Go. Они предоставляют семантические названия наборов поведений и состояний. Фундаментальное различие между ролями и классами в том, что роли не инстанцируют объекты.[58]

Хоть роли и отличаются от классов, возможно написать код, создающий объект из роли. Попытка использовать роль для создания объекта приведёт к созданию класса с тем же именем. В документации Raku этот механизм назван автоматическим каламбурированием ролей, т.к. сгенерированный класс является каламбуром.[59]

В сущности, роли — пачки атрибутов и потенциально абстрактных методов, которые могут быть добавлены в класс без использования наследования. Роль может быть добавлена даже к отдельному объекту. В последнем случае, Raku создаст анонимный подкласс, добавит к нему роль и заменит класс объекта на этот анонимный подкласс.

Например, собака — это млекопитающее, потому что собаки наследуют у млекопитающих некоторые черты, такие как молочные железы и, через их предков позвоночных, позвоночник. С другой стороны, собаки могут обладать разными типами поведения, которые могут меняться со временем. Например, собака может быть домашней, бродячей, быть поводырём. Эти наборы дополнительных поведений могут быть добавлены к собаке. Можно описать их таким образом, чтобы можно было их применять по отношению к другим животным. Например, кошка может быть домашней и бродячей. Собака и кошка отличаются друг от друга, но остаются в общей категории млекопитающих. Итак, Млекопитающее — это класс, Собака и Кошка — классы, унаследованные от млекопитающего. Но вышеназванные поведения — это роли, которые можно добавить в классы или объекты, созданные из классов.

class Млекопитающее is Позвоночное {
    ...
}
class Собака is Млекопитающее {
    ...
}
role Питомец {
    ...
}
role Бездомный {
    ...
}
role Поводырь {
    ...
}

Роли добавляются к классам и объектам с помощью ключевого слова does. Для наследования же используется ключевое слово is. Эти слова отражают различие в смысле этих возможностей языка: присоединение роли наделяет класс поведением роли, но не означает, что этот класс становится буквально тем же самым, что и эта роль.

class СобакаПоводырь is Собака does Поводырь {
    ...
}   # Подкласс присоединяет роль.

my $собака = Собака.new();
$собака does Поводырь;       # Объект присоединяет роль.

И роли, и классы являются типами. Роль может быть использована в объявлении переменной. Например, роль Незрячий может содержать атрибут типа Поводырь, в котором может быть собака-поводырь, лошадь-поводырь, человек-поводырь или даже машина-поводырь.

class Человек {
    has Собака $собака;     # Может содержать любой вид собаки —
    ...                     # не важно, Поводырь это или нет.
}

role Незрячий {
    has Поводырь $поводырь; # Может содержать любой объект с ролью
    ...                     # Поводырь — не важно, Собака это или нет.
}

Регулярные выражения править

Регулярные выражения и обработка строк всегда были одними из определяющих особенностей Perl.[60] Поскольку шаблоны Perl в определенный момент превзошли возможности регулярных выражений,[61] документация Raku называет их просто регексами, дистанцируясь от формального определения регулярных выражений.

Raku расширяет набор функций Perl в отношении регулярных выражений, вкладывая их в бо́льший фреймворк для создания парсеров, называемый правилами.[62] Правила предоставляют возможности контекстно-зависимого разбора (такие как синтаксический предикат из PEG и ANTLR) и ведут себя как замыкания относительно своих лексических областей видимости.[63] Правила вводятся с помощью ключевого слова rule, использование которого похоже на определение подпрограммы. Анонимные же правила могут быть введены с помощью ключевого слова regex (или rx), или их можно описывать как регулярные выражения в Perl — с помощью операторов m (сопоставление) или s (замена).

В Апокалипсисе 5 Ларри Уолл перечисляет 20 проблем текущей «культуры использования регулярных выражений». В числе прочего, регулярные выражения Perl были «слишком компактными и „милыми“», они «слишком надеялись на слишком небольшой набор специальных символов», у них была «слабая поддержка именованного захвата», «слабая поддержка грамматик» и «плохая интеграция с языком».[64]

Синтаксические упрощения править

Некоторые конструкции Perl в Raku были изменены и оптимизированы для других синтаксических оборотов. Например, круглые скобки, которые были обязательны в инструкциях порядка выполнения, теперь опциональны.[49]

if is-true() {
    for @array {
        ...
    }
}

Оператор , (запятая) теперь является конструктором списков, поэтому скобки вокруг списков не требуются.

@array = 1, 2, 3, 4;

Цепочки сравнений править

Raku разрешает следующие выражения:

if 20 <= $temperature <= 25 {
    say "Температура в комнате — от 20 до 25 градусов!"
}

Это воспринимается как последовательные сравнения слева направо с последующим объединением через логическое И.

Ленивые вычисления править

Raku использует технику ленивых вычислений списков подобно некоторым функциональным языкам, таким как Haskell:[65]

@integers = 0..Inf; # целые числа от нуля до бесконечности

Этот код не выдаст ошибку, пытаясь поместить бесконечный список в массив @integers, и не зависнет, пытаясь бесконечно увеличивать список, если запрашиваться будет конечное число элементов.

Это упрощает многие распространенные в Raku задачи, в том числе операции ввода-вывода, трансформации списков и передачу параметров.

Возможно также создание ленивых списков с помощью ключевых слов gather и take. Они похожи на генераторы в языках Icon и Python.

my $squares = lazy gather for 0..Inf {
    take $_ * $_;
};

Здесь $squares — это бесконечный список квадратов натуральных чисел (включая ноль), но благодаря ленивой природе этого списка, элементы вычисляются только тогда, когда к ним происходит доступ.[66]

Скрещения править

Raku вводит концепцию скрещений[67] (англ. junction — соединение, место пересечения; в Raku этот термин имеет также отношение к конъюнкции и дизъюнкции[65]). Это суперпозиция нескольких значений.[65] В простейшем виде, скрещение создаётся операторами скрещения:

# Пример скрещения типа | ("any"):
my $color = 'белый';
unless $color eq 'белый' | 'чёрный' | 'серый' {
    die "Печать этим цветом не поддерживается.\n";
}

# Пример скрещения типа & ("all"):
my $password = 'secret!123';
if $password ~~ /<:alpha>/ & /<:digit>/ & /<:punct>/ {
    say "Ваш пароль достаточно надёжен.";
}

Оператор | выражает значение равное либо левому, либо правому аргументу, оператор & — одновременно и левому, и правому. Эти значения могут быть использованы в коде везде, где по смыслу предполагается одно значение. Любые операции со скрещением действуют одновременно на все его составляющие, и результат объединяется через оператор этого скрещения. Так, ("apple"|"banana") ~ "s" вернёт "apples"|"bananas". Однако в булевом контексте скрещения возвращают лишь одно значение — истину или ложь: any возвращает истину, если сравнение истинно для хотя бы одного элемента; all возвращает истину, если сравнение истинно для всех элементов.[68]

Используя скрещения, можно дополнить систему типов некой формой обобщенного программирования, ограничивающей переменные скрещениями типов.

subset Color of Any where RGB_Color | CMYK_Color;
sub get_tint(Color $color, Num $opacity) {
    ...
}

Скрещения — это особые объекты, разделяющие выполнение кода на потенциально-параллельные потоки. И они созданы специально для применения в булевом контексте: нельзя получить доступ к их содержимому непосредственно, без конвертации в строку, что отличает их, например, от множеств и других коллекций.[68]

Макросы править

В низкоуровневых языках, макросы стали синонимом текстовой замены в исходном коде из-за ассоциаций с препроцессором языка Си. Однако в высокоуровневых языках, таких как Лисп, который появился раньше Си, макросы были более мощными.[69] Этой лиспоподобной концепцией макросов Raku и воспользовался.[48] Мощность этого типа макросов базируется на оперировании программой как высокоуровневой структурой данных, а не текстом, и на доступе ко всем возможностям языка.

Определение макроса в Raku выглядит подобно определению подпрограммы или метода. И оперировать такой макрос может и исходным кодом, и абстрактным синтаксическим деревом, и комбинацией этих двух вещей.

macro hello($what) {
    quasi { say "Hello { {{{$what}}} }" };
}

В примере выше, парсинг аргумента макроса происходит до исполнения макроса, что ведёт к более информативным диагностическим сообщениям компилятора. Тем не менее, поскольку исполнение тела макроса происходит во время компиляции (для каждого случая использования), могут быть применены самые разные техники оптимизации. С помощью макросов возможно даже произвести большую часть работы некоторых программ до начала их выполнения.

Идентификаторы править

В Raku идентификаторы, помимо букв, цифр и подчеркиваний, могут также содержать апострофы и дефисы, при условии, что после них обязательно идут буквы. Буквы включают «соответствующие» (какие — зависит от реализации) символы Юникода, которые в Rakudo и MoarVM определены как все символы Юникода категории «L».[70]

Использование дефисов вместо подчеркиваний называется «kebab case».[71][72][73]

Метаоператоры править

Метаоператоры — операторы, параметризующиеся другими операторами, подобно тому, как функции могут принимать другие функции в качестве параметров.[74]

Метаоператор присваивания править

Perl унаследовал такие операторы языка Си, как +=, *= и т.п. Raku обобщает их до метаоператора. Для любого бинарного оператора op мы можем написать:

$x op= $y;  # или $x [op]= $y

Что значит:

$x = $x op $y;

Причем, это работает и для операторов, определённых пользователем.

Гипероператоры править

Они похожи на оператор map в Perl. Заставляют операторы работать со всеми значениями массива. Могут применяться как к бинарным, так и к унарным операторам.[75]

Например, следующий код создаст массив, содержащий все элементы массива @a, увеличенные на единицу:

my @aPlusOne = @a »+» 1;    # или @a >>+>> 1

Направление угловых скобок влияет на поведение при передаче в качестве параметров массивов разной длины.[75] Эти «стрелки» показывают, откуда берётся длина результата операции.

Пример использования гипероператора с унарным оператором:

my @a = 1, 2, -3;
my @b = -<<@a;      # [-1 -2 3]

Гипероператоры работают не только для плоских, но и для вложенных массивов.[76]

Метаоператор редукции править

Метаоператор редукции может использоваться с любым инфиксным оператором, преобразуя его в оператор свёртки списка. Это похоже на то, как если бы оператор был применён к первым двум элементам, затем к получившемуся значению и третьему элементу и т.д., пока не останется только одно значение. В качестве оператора-параметра может выступать сумма, произведение, максимум, минимум и т.д. Это чрезвычайно мощный механизм, который, например, переводит оператор + в оператор суммы списка, как в примере ниже.

say "Сумма целых чисел от 0 до 99 равна: ", [+] ^100;

Кросс-оператор править

Ведёт себя одновременно и как оператор, и как метаоператор.[77]

Кросс-оператор[75] находит прямое произведение списков, упорядоченное таким образом, что перечисление элементов из правого операнда происходит быстрее, чем из левого,[77] возвращая последовательность списков:

1..3 X <a b c> X <d e f>;
# ((1 a d) (1 a e) (1 a f) 
#  (1 b d) (1 b e) (1 b f)
#  (1 c d) (1 c e) (1 c f)
#  (2 a d) (2 a e) (2 a f)
#  (2 b d) (2 b e) (2 b f)
#  (2 c d) (2 c e) (2 c f)
#  (3 a d) (3 a e) (3 a f)
#  (3 b d) (3 b e) (3 b f)
#  (3 c d) (3 c e) (3 c f))

Метаоператор сворачивает внутренние списки с помощью оператора-параметра:[77]

1..3 X~ <a b c> X~ <d e f>;
# (1ad 1ae 1af 1bd 1be 1bf 1cd 1ce 1cf
#  2ad 2ae 2af 2bd 2be 2bf 2cd 2ce 2cf
#  3ad 3ae 3af 3bd 3be 3bf 3cd 3ce 3cf)

Зип-оператор править

От англ. zipper — застёжка-молния.[78]

Аналогично кросс-оператору, совмещает элементы списков,[75] но возвращает последовательность, содержащую сначала первые элементы каждого списка, затем вторые элементы каждого списка и т.д.[79]

<a b c> Z <1 2 3 4>;
# ((a 1) (b 2) (c 3))

100, 200 Z+ 42, 23;
# (142 223)

Обратные операторы править

Метаоператор R (англ. reversed) позволяет менять местами аргументы исходного оператора.

say "Один делить на три равно ", 3 R/ 1;

Вложенность метаоператоров править

Результатом применения метаоператора к оператору является другой оператор, к которому снова может быть применен метаоператор и т.д. Для устранения неоднозначности в синтаксисе разрешено использовать квадратные скобки.[80]

my @a = 1, 2, 3;
my @b = 5, 6, 7;

@a >>>>> @b;        # Ошибка разбора.
@a >>[>]>> @b;      # [False False False]
# Здесь гипероператор >> >> применяется к оператору сравнения.

# Кросс-метаоператор применяется
# к метаоператору присваивания, параметризованному
# оператором сложения:
@a X[+=] @b;        # (6 12 19 7 13 20 8 14 21)

# Из-за кросс-метаоператора, присваивание делалось
# для каждого элемента массива @a с каждым элементом массива @b,
# что эквивалентно прибавлению к каждому элементу массива @a
# суммы элементов массива @b:
say [+] @b;         # 18
say @a;             # [19 20 21]

Конкурентность и параллелизм править

Подобно другим современным языкам, Raku спроектирован для поддержки параллелизма и асинхронного программирования.

Raku предоставляет простой модульный высокоуровневый API для написания конкурентного кода, независящий от способов реализации этого API виртуальной машиной. Кроме того, некоторые функции языка могут неявно работать асинхронно. Чтобы обеспечить управляемость и совместимость между этими функциями, пользовательскому коду следует избегать, насколько это возможно, использования низкоуровневых интерфейсов (потоков, планировщиков, блокировок).[81]

Центральным высокоуровневым механизмом являются промисы[82][83] (англ. Promise — обещание), представляющие собой результаты вычислений, полученные до их фактического завершения. Их можно давать, выполнять и нарушать. Таким образом, они обладают тремя возможными состояниями. Сила этого механизма заключается в возможности их комбинировать и соединять в цепочки:

my $p1 = Promise.new();
my $p2 = $p1.then({ say "Результат второго промиса."});

Здесь then обеспечивает выполнение $p2 лишь после выполнения $p1.

Есть также англ. Supplies («запасы») и англ. Suppliers («поставщики») — механизм создания асинхронных потоков данных с возможностью обработки каждого сообщения сразу несколькими получателями, подобно тому, как работают обработчики событий в других языках программирования.[81] Этот механизм можно использовать для событийно-ориентированного программирования.

Наконец, каналы (англ. Channels) — это потокобезопасные FIFO-очереди, подобные именованным конвейерам в операционных системах, но функционирующие в рамках текущего процесса. Ключевое отличие от Supply в том, что чтение из канала является удалением из очереди,[81] т.е. одно значение может быть прочитано лишь единожды.

Примеры править

Hello world править

Программа «Здравствуй, мир!» часто используется для демонстрации базового синтаксиса языка. На языке Raku она выглядит так:

say 'Hello, world';

Хотя, конечно, есть больше одного способа выразить это.[84]

Факториал править

Вычисление факториала, определённое несколькими способами:

# С использованием рекурсии с конструкцией «if-else».
sub fact( UInt $n --> UInt ) {
    if $n == 0 { 1 }
    else       { $n * fact($n-1) }
}

# С использованием рекурсии с «if»
# в качестве модификатора выражения.
sub fact( UInt $n --> UInt ) {
    return 1 if $n == 0;
    return $n * fact($n-1);
}

# С использованием рекурсии с конструкцией «when».
sub fact( UInt $n --> UInt ) {
    when $n == 0 { 1 }
    default      { $n * fact($n-1) }
}

# С использованием тернарного оператора.
sub fact( UInt $n --> UInt ) {
    $n == 0 ?? 1 !! $n * fact($n-1)
}

# С использованием множественной диспетчеризации.
multi fact(0) { 1 }
multi fact( UInt $n --> UInt ) {
    $n * fact($n - 1)
}

# С использованием метаоператора редукции.
sub fact( UInt $n --> UInt ) {
    [*] 1..$n
}

# Определение оператора факториала,
# реализованного через метаоператор редукции.
sub postfix:<!>( UInt $n --> UInt ) { [*] 1..$n }

# С использованием ключевого слова «state» для мемоизации.
sub fact( UInt $n --> UInt ) {
    state %known = 0 => 1;
    return %known{$n} if %known{$n}:exists;
    %known{$n} = $n * fact($n-1);
    return %known{$n};
}

QuickSort править

QuickSort — известный алгоритм сортировки. Его реализация, использующая функциональную парадигму, может быть лаконично записана[a] так:

# Отсортированный пустой список — это пустой список.
multi quicksort([]) { () }

# Иначе, берём первый элемент в качестве опорного...
multi quicksort([$pivot, *@rest]) {
    # Делим элементы на список тех,
    # которые меньше опорного, и те,
    # которые больше опорного.
    my @before = @rest.grep(* before $pivot);
    my @after  = @rest.grep(* after $pivot);

    # Сортируем эти подсписки и объединяем результат.
    flat (quicksort(@before), $pivot, quicksort(@after))
}
  1. Если компилятор не сделает что-нибудь загадочное за кулисами, максимальная глубина рекурсии здесь — длина списка, что делает эту реализацию непригодной для больших данных. Глубина рекурсии может быть сокращена до log2(длина_списка), если использовать рекурсию только с небольшими подсписками before и after, и циклы в других случаях. Также, в этой реализации дублирующиеся значения исходного списка появятся в выводе лишь единожды, т.к. оба сравнения в параметрах метода grep строгие.

Ханойская башня править

Эта головоломка часто используется для знакомства с рекурсией в информатике. Данная реализация использует мультиметоды с литералом 0 как часть сигнатуры.

multi sub hanoi(0, $, $, $) { }                         # Нет дисков. Нечего перекладывать.
multi sub hanoi($n, $a = 'A', $b = 'B', $c = 'C') {     # $n дисков и три стержня: A, B, C.
    hanoi $n - 1, $a, $c, $b;                           # Переместить ($n - 1) дисков с A на B
    say "Переместить диск $n с $a на $c.";              # Переместить последний диск с A на C.
    hanoi $n - 1, $b, $a, $c;                           # Переместить ($n - 1) дисков с B на C.
}

hanoi(5);   # Решение для пяти дисков.

См. также править

Примечания править

  1. Официальный сайт Rakudo (англ.). — «楽土». Дата обращения: 26 июля 2022. Архивировано 28 июля 2022 года.
  2. 楽土(らくど) の意味 (яп.). goo国語辞書. — «心配や苦労がなく楽しい生活ができる土地。». Дата обращения: 27 августа 2021. Архивировано 27 августа 2021 года.
  3. Perl 6 becomes Raku - but what does this mean? (англ.). Edument. — «It means “comfort” or “ease” in Japanese, which nicely reflects the goals of the language to be a comfortable programming experience - as mentioned earlier, often at the expense of those doing the language implementation! The most popular compiler for the language is named “Rakudo”, which approximately means “way of the camel” (the camel being a symbol commonly associated with Perl) and also “paradise”. Thus, we can see it as a way to “do” the Raku language.» Дата обращения: 27 августа 2021. Архивировано 27 августа 2021 года.
  4. Definition of 楽 (англ.). JapanDict: Japanese Dictionary. — «Buddhism: sukha (happiness)». Дата обращения: 30 августа 2021. Архивировано 30 августа 2021 года.
  5. Perl 6 FAQ (англ.). — «Perl 6 will provide a "Perl 5 compatibility mode", allowing the compiler to directly execute any code that it recognizes as being written in Perl 5. [...] In Q2 2010 Patrick Michaud will release a useful and usable (but not feature complete) Perl 6 compiler...» Дата обращения: 3 сентября 2021. Архивировано 3 сентября 2021 года.
  6. 1 2 Larry has approved renaming Perl 6 to Raku. Дата обращения: 18 октября 2019. Архивировано 15 октября 2019 года.
  7. Perl 6 Summary for the week ending 20030713. Perl 6 Rules at OSCON. (англ.). Perl 6 Archive (13 июля 2003). — «Damian spoke about Perl6::Rules, his implementation of Perl 6's rules system in pure Perl 5. [...] he told us [...] that the module would be completed and released to CPAN as time/money allowed and would be out by Christmas. He didn't say which Christmas.» Дата обращения: 27 августа 2021. Архивировано 27 августа 2021 года.
  8. Perl Humour: Perl 6 and Vapourware (англ.). Perl Beginners' Site. — «<anonuser> You know for when they finally decide to release that programatic abortion they call perl 6 <rindolf> anonuser: on Christmas. <rindolf> anonuser: don't know which one.» Архивировано 8 апреля 2012 года.
  9. Perl 6 goes live — Larry Wall on Twitter. Дата обращения: 27 декабря 2015. Архивировано 8 марта 2016 года.
  10. OpenNET: Состоялся рождественский релиз Perl 6 (первый релиз языка). Дата обращения: 15 июля 2021. Архивировано 15 июля 2021 года.
  11. Christmas is here Архивная копия от 27 декабря 2015 на Wayback Machine.
  12. Federico Biancuzzi. Masterminds of Programming: Conversations with the Creators of Major Programming Languages / Federico Biancuzzi, Shane Warden. — 2009. — ISBN 978-0596515171.
  13. Kline, Joe. Report from the Perl Conference (21 августа 2000). Дата обращения: 26 июля 2021. Архивировано 4 июня 2009 года.
  14. Wall, Larry. State of the Onion 2000. O'Reilly Network (23 октября 2000). Дата обращения: 26 июля 2021. Архивировано 6 июня 2010 года.
  15. The Perl Foundation. About Perl 6 RFCs. Дата обращения: 26 июля 2021. Архивировано 26 июля 2021 года.
  16. Wall, Larry. Apocalypse 1: The Ugly, the Bad, and the Good (2 апреля 2001). Дата обращения: 26 июля 2021. Архивировано 26 июля 2021 года.
  17. Raku test suite. Дата обращения: 26 июля 2021. Архивировано 26 июля 2021 года.
  18. Larry Wall and the Perl 6 designers. Perl 6 Design Documents. Дата обращения: 26 июля 2021. Архивировано 26 июля 2021 года.
  19. The Perl Foundation. Exegeses. Дата обращения: 26 июля 2021. Архивировано 26 июля 2021 года.
  20. Barewords - "голые" слова в Perl. Дата обращения: 14 августа 2021. Архивировано 14 августа 2021 года.
  21. FIO00-PL. Do not use bareword file handles. (англ.). SEI CERT Perl Coding Standard. Carnegie Mellon University (16 ноября 2017). Дата обращения: 14 августа 2021. Архивировано 14 августа 2021 года.
  22. Wall, Larry. Apocalypse 3: Operators (англ.). Perl 6 Archive (2 октября 2001). Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  23. Wall, Larry. Apocalypse 4: Syntax (англ.). Perl 6 Archive (18 января 2002). Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  24. Wall, Larry. Apocalypse 12: Objects (англ.). Perl 6 Archive (13 апреля 2004). Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  25. Simon Proctor (‎Scimon‎). Day 19 – Functional Programming with Raku (англ.). Raku Advent Calendar (19 декабря 2019). Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  26. A Plan for Pugs (англ.). Perl.com (3 марта 2005). — Интервью с Autrijus Tang (Одри Тан). — «chromatic: Have you started giving Haskell tutorials? I know Larry and Patrick have started to pick up some of it. I’m pretty sure Luke and Damian have already explored it (or something from the same family tree). Autrijus: I think I’ve read a paper from Damian that says he taught Haskell in monash. It’s before the monadic revolution though. chromatic: If not Haskell, certainly something from the ML family. Autrijus: Right. So, I’ve been pointing people to YAHT and #Haskell. chromatic: It sounds like you’re attracting people from both sides of the fence then. Autrijus: It indeed is. I get svn/svk patches and darcs patches.» Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  27. Camelia (англ.). Дата обращения: 14 августа 2021. Архивировано 14 мая 2021 года.
  28. Larry Wall in IRC chat log (15 января 2016). Дата обращения: 10 ноября 2017. Архивировано из оригинала 8 апреля 2016 года. (см. код страницы)
  29. Archived "Logo considerations" email from Larry Wall (24 марта 2009). Дата обращения: 10 ноября 2017.
  30. Download Raku Архивная копия от 12 августа 2021 на Wayback Machine: «Rakudo is currently the most actively developed and mature implementation of Raku».
  31. 1 2 Wall, Larry. Synopsis 1: Overview (10 августа 2004). Дата обращения: 15 августа 2021. Архивировано 15 августа 2021 года.
  32. GitHub Issues: compile to jar files / moarvm files Архивная копия от 15 июля 2021 на Wayback Machine — обсуждение возможности распространения скомпилированного байт-кода.
  33. Getting started with node.js rakudo.js. Дата обращения: 15 июля 2021. Архивировано 15 июля 2021 года.
  34. Worthington, Jonathan MoarVM: A virtual machine for NQP and Rakudo. 6guts. Дата обращения: 24 июля 2013. Архивировано 9 июля 2013 года.
  35. MoarVM. MoarVM team. Дата обращения: 8 июля 2017. Архивировано 6 июня 2017 года.
  36. Development Release #85 (“Berlin”) Архивная копия от 15 июля 2021 на Wayback Machine: «this is the last release of Rakudo that supports Parrot as a backend for the foreseeable future».
  37. YAPC::Europe 2013 “Future Perl”: MoarVM: a metamodel-focused runtime for NQP and Rakudo By Jonathan Worthington (‎jnthn‎) Архивная копия от 16 июля 2021 на Wayback Machine: «We know what we need now» (шестой слайд)
  38. YAPC::Europe 2013 “Future Perl”: MoarVM: a metamodel-focused runtime for NQP and Rakudo By Jonathan Worthington (‎jnthn‎) Архивная копия от 16 июля 2021 на Wayback Machine — страница выступления на сайте конференции с видео
  39. Pugs — Perl 6 user's golfing system.
  40. Feature comparison of Perl 6 compilers. Архивировано 7 февраля 2019 года.
  41. Integrating the Pugs test suite into the Synopses (англ.) (22 августа 2006). — «Well, in short, we have divided the .t files in the Pugs test suite into pieces and inserted every resulting snippet after the corresponding paragraph of the Synopses.» Дата обращения: 28 августа 2021. Архивировано 28 августа 2021 года.
  42. agentz. Raku / mu: [t/statements/do.t] (англ.). GitHub (16 августа 2006). Дата обращения: 28 августа 2021. Архивировано 28 августа 2021 года.
  43. [gsoc_spectest] moved do.t into spec, added tests, fudged for rakudo (added 3 tests) (англ.). GitHub. Дата обращения: 28 августа 2021. Архивировано 28 августа 2021 года.
  44. Search · pugscode.org (англ.). GitHub. — «4,590 commit results in Raku/roast». Дата обращения: 31 августа 2021. Архивировано 31 августа 2021 года.
  45. Interview with Audrey Tang (англ.). Andrew Shitov (5 мая 2015). — «In August 2006, Yichun Zhang improved the continuous integration system, displaying tests inline with the spec, as detailed in this writeup. This makes the tests part of the spec, not particular to Pugs. In January 2008, Larry implemented a fudge program that adapts the test suite to work on new implementations such as SMOP and Rakudo. In February 2015, the community declared the tests at perl6/roast as the actual specification...» Дата обращения: 28 августа 2021. Архивировано 28 августа 2021 года.
  46. 1 2 Wall, Larry. Synopsis 2: Bits and Pieces (20 мая 2009). Дата обращения: 15 августа 2021. Архивировано 8 мая 2021 года.
  47. WDH: PERL - Подпрограммы (6.6.7. Прототипы). Дата обращения: 15 августа 2021. Архивировано 23 апреля 2022 года.
  48. 1 2 3 Wall, Larry. Synopsis 6: Subroutines (21 марта 2003). Дата обращения: 15 августа 2021. Архивировано 15 августа 2021 года.
  49. 1 2 Wall, Larry. Synopsis 4: Blocks and Statements (20 мая 2009). Дата обращения: 15 августа 2021. Архивировано 15 августа 2021 года.
  50. Объектно-ориентированное программирование в Perl 5. Записки программиста (7 апреля 2011). Дата обращения: 21 августа 2021. Архивировано 21 августа 2021 года.
  51. Wall, Larry. Synopsis 12: Objects (18 августа 2006). Дата обращения: 21 августа 2021. Архивировано 21 августа 2021 года.
  52. Classes and objects. Constructors. (англ.). Raku Documentation. Дата обращения: 21 августа 2021. Архивировано 21 августа 2021 года.
  53. Кроссбраузерные аксессоры в JavaScript. Хабр (20 апреля 2011). Дата обращения: 22 августа 2021. Архивировано 22 августа 2021 года.
  54. Object orientation. Classes. Attributes. (англ.). Raku Documentation. Дата обращения: 21 августа 2021. Архивировано 21 августа 2021 года.
  55. The Software Composition Group. Traits. Дата обращения: 22 сентября 2006. Архивировано 11 августа 2006 года.
  56. Jonathan Worthington. Day 18: Roles. Дата обращения: 21 августа 2021. Архивировано 21 августа 2021 года.
  57. Роли. Введение в Raku. Дата обращения: 15 июля 2021. Архивировано 15 июля 2021 года.
  58. chromatic. The Why of Perl Roles. Дата обращения: 21 августа 2021. Архивировано 16 июля 2021 года.
  59. Object orientation. docs.raku.org. Дата обращения: 22 августа 2021. Архивировано 21 августа 2021 года.
  60. Parlante, Nick. Essential Perl: String Processing with Regular Expressions. Дата обращения: 21 августа 2021. Архивировано 21 апреля 2012 года.
  61. Christiansen, Tom. PERL5 Regular Expression Description. — «Perl's regexps "aren't" -- that is, they aren't "regular" because backreferences per sed and grep are also supported, which renders the language no longer strictly regular». Дата обращения: 25 марта 2010. Архивировано 31 марта 2010 года.
  62. Grammars. Rules. (англ.). Raku Documentation. Дата обращения: 22 августа 2021. Архивировано 22 августа 2021 года.
  63. Wall, Larry. Synopsis 5: Regexes and Rules (20 мая 2009). Дата обращения: 22 августа 2021. Архивировано 22 августа 2021 года.
  64. Wall, Larry. Apocalypse 5: Pattern Matching (4 июня 2002). Дата обращения: 22 августа 2021. Архивировано 22 августа 2021 года.
  65. 1 2 3 Wall, Larry. Synopsis 9: Data Structures (13 сентября 2004). Дата обращения: 22 августа 2021. Архивировано 22 августа 2021 года.
  66. Control flow: gather/take (англ.). Raku Documentation. — «The gather/take combination can generate values lazily, depending on context. If you want to force lazy evaluation use the lazy subroutine or method. Binding to a scalar or sigilless container will also force laziness.» Дата обращения: 22 августа 2021. Архивировано 21 августа 2021 года.
  67. 8.6. Скрещение. Введение в Raku. Дата обращения: 15 июля 2021. Архивировано 15 июля 2021 года.
  68. 1 2 class Junction (англ.). Raku Documentation. Дата обращения: 23 августа 2021. Архивировано 23 августа 2021 года.
  69. Lamkins, David B. Successful Lisp: How to Understand and Use Common Lisp. — bookfix.com, 2004-12-08. Архивная копия от 12 сентября 2006 на Wayback Machine Источник. Дата обращения: 23 августа 2021. Архивировано из оригинала 12 сентября 2006 года.
  70. syntax identifiers (англ.). Raku Documentation. Дата обращения: 23 августа 2021. Архивировано 23 августа 2021 года.
  71. Lodash “Array” Methods: kebabCase (англ.). Дата обращения: 23 августа 2021. Архивировано 14 августа 2021 года.
  72. Prop Casing (camelCase vs kebab-case) (англ.). Vue.js. Дата обращения: 23 августа 2021. Архивировано 12 августа 2021 года.
  73. Ivan Grishaev. Configuration in Clojure. Environment Variables in Clojure. (англ.) (6 мая 2021). Дата обращения: 23 августа 2021. Архивировано 23 августа 2021 года.
  74. Operators: Metaoperators (англ.). Дата обращения: 24 августа 2021. Архивировано 3 августа 2021 года.
  75. 1 2 3 4 Андрей Шитов. Метаоператоры в Perl 6. Pragmatic Perl (27 мая 2015). Дата обращения: 23 августа 2021. Архивировано 23 августа 2021 года.
  76. Hyper operators (англ.). Raku Documentation. Дата обращения: 24 августа 2021. Архивировано 3 августа 2021 года.
  77. 1 2 3 Operators. List infix precedence: infix X (англ.). Raku Documentation. Дата обращения: 24 августа 2021. Архивировано 3 августа 2021 года.
  78. Kurt Nørmark. Functional Programming in Scheme. Reduction and zipping (англ.). Department of Computer Science, Aalborg University, Denmark. — «The zipping function is named after a zipper, as known from pants and shirts.» Дата обращения: 24 августа 2021. Архивировано 24 августа 2021 года.
  79. Operators. List infix precedence: infix Z (англ.). Дата обращения: 24 августа 2021. Архивировано 3 августа 2021 года.
  80. Operators. Metaoperators. Nesting of metaoperators. (англ.). Raku Documentation. Дата обращения: 24 августа 2021. Архивировано 3 августа 2021 года.
  81. 1 2 3 Concurrency (англ.). Raku Documentation. Дата обращения: 25 августа 2021. Архивировано 21 августа 2021 года.
  82. Промисы. Современный учебник JavaScript (15 июля 2020). Дата обращения: 27 августа 2021. Архивировано 27 августа 2021 года.
  83. Promise. MDN. — «исполнение промиса протоколируется при помощи продолжения p1.then. Это показывает как синхронная часть метода отвязана от асинхронного завершения промиса». Дата обращения: 27 августа 2021. Архивировано 26 августа 2021 года.
  84. Raku - Difference between print, put and say? (англ.). Stack Overflow. Дата обращения: 1 сентября 2021. Архивировано 1 сентября 2021 года.
  85. People of Perl 6: Carl Mäsak (англ.). Perl.com (31 августа 2010). — Интервью с разработчиком Rakudo по имени Carl Mäsak. — «I’ve also gained a new respect for what a “holistic” process the design of a language such as Perl 6 can be sometimes. Whether some feature turns out to be a good idea is determined by dozens of minute interactions in the spec, not all of them “local”, and some of them outright emergent.» Дата обращения: 29 августа 2021. Архивировано 29 августа 2021 года.
  86. Larry Wall. Perl, the first postmodern computer language (англ.). Perl.com (9 марта 1999). — Текст выступления Ларри Уолла на Linux World третьего марта 1999 года. Дата обращения: 30 августа 2021. Архивировано 11 августа 2021 года.

Литература править

Книги, опубликованные до релиза языка (до версии 6.c) править

  • Allison Randal, Dan Sugalski, Leopold Tötsch. Perl 6 and Parrot Essentials. — O'Reilly Media, 2004. — 279 p. — ISBN 059600737X, 9780596007379.
  • Scott Walters. Perl 6 Now: The Core Ideas Illustrated with Perl 5 (Электронная книга Google). — Apress, 2004. — 424 p. — ISBN 1590593952, 9781590593950.
  • Мориц Ленц (Moritz Lenz, Германия), перевод Анатолия Шарифулина (уроки 1—6) и Андрея Шитова (7—20). от Perl 5 к Perl 6 // Сетевые решения. — Минск: ИД "Нестор", 2008. — № 9.

Ссылки править