2. Что такое мультифункции в Perl 6

В Perl 6 есть ключевое слово multi, которое создает так называемые мультифункции (multi-subs). Это ни что иное как множественная диспетчеризация (multiple dispatch), встроенная в язык.

В отличие от обычных функций, которые объявляются со словом sub, мультифункции требуют двух слов: multi sub. Имя функции при этом остается одним и тем же для всего набора мультифункций. В зависимости от выполненных условий, компилятор выбирает один из вариантов функции.

Число аргументов

Рассмотрим несколько примеров. Первый пример — вычисление расстояния от начала координат до точки на прямой, на плоскости или в трехмерном пространстве.

multi sub dist($x) {
    return $x;
}

multi sub dist($x, $y) {
    return sqrt($x ** 2 + $y ** 2);
}

multi sub dist($x, $y, $z) {
    return sqrt($x ** 2 + $y ** 2 + $z ** 2);
}

say dist(2);        # 2
say dist(3, 4);     # 5
say dist(8, 9, 12); # 17

В этом примере функции различаются исключительно числом аргументов. При вызове, Perl 6 однозначно определяет, какой из вариантов следует вызвать.

Типы аргументов

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

multi sub mirror(Int $i) {
    -$i
}

multi sub mirror(Str $s) {
    $s.flip
}

say mirror(42);   # -42
say mirror('42'); # 24

Здесь функция возвращает должна вернуть «зеркальный» вариант своего аргумента, чтобы это ни значило. Точный смысл вы в праве установить самостоятельно для каждого типа аргумента. Для целых чисел (Int $i) это будет противоположное число, а для строки (Str $s) — строка, записанная в обратном порядке.

Точно так же возможно определить свой класс и дополнить мультифункцию соответствующим вариантом. Во-первых, определим класс для светофора, у которого есть текущее значение value. Во-вторых, создадим мультифункцию, которая ожидает такой объект и инвертирует его:

class TrafficLight {
    has Str $.value;
}

multi sub mirror(TrafficLight $obj) {
    $obj.value eq 'red' ?? 'green' !! 'red'
}

say mirror(TrafficLight.new(value => 'green')); # red

Ограничение на значение аргументов

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

multi sub set-password($pwd) {
    say "Password '$pwd' is OK"
}

multi sub set-password($pwd where {$pwd.chars <= 5}) {
    say "Password '$pwd' is too short!"
}

set-password('He11oW0rld!'); # OK
set-password('qwert');       # too short!

Во втором варианте функции значение аргумента уточняется с помощью ключевого слова where:

multi sub set-password($pwd where {$pwd.chars <= 5}) { . . . }

Эта функция будет вызвана только в том случае, если выполняется условие $pwd.chars <= 5, то есть когда строка недостаточно длинна.

Обратите внимание, что для первого варианта функции никаких ограничений нет, тем не менее, Perl 6 принимает совершенно правильно решение, опираясь на весь комплект функций, и не активирует этот вариант для короткой строки.

На сегодня все. Завтра будем использовать мультифункции для создания рекурсии.

1. Ресурсы про Perl 6

Давайте начнем новый сезон с того, что посмотрим, где сейчас идет движуха по поводу шестого перла.

Язык

Во-первых, есть официальная точка входа — сайт perl6.org.

Screen Shot 2017-12-31 at 12.24.53.png

Один из самых ценных разделов на этом сайте — документация (docs.perl6.org), содержащая достаточно подробное описанием синтаксиса, встроенных функций и классов. Иногда документации недостаточно, но почти всегда можно найти примеры использования описываемых языковых конструкций.

Screen Shot 2017-12-31 at 12.27.30.png

Софт

Следующий важный сайт — rakudo.org. Rakudo (или полностью — Rakudo Perl 6) — это лучшая (да, в целом, просто единственная) на сегодня полноценная реализация компилятора. За последние два-три года Ракудо радикально улучшился — перестал падать и стал работать достаточно быстро (об этом мы еще поговорим отдельно).

Если вы не собираетесь исследовать внутренности компилятора, а хотите просто загрузить компилятор, идите прямиком на страницу загрузки Rakudo Star — это набор, состоящий из компилятора, виртуальной машины и еще нескольких полезных модулей и утилит.

Screen Shot 2017-12-31 at 12.28.38.png

Текущий аналог CPAN для Perl 6 — утилита zef (она идет вместе с Rakudo Star) и сайт modules.perl6.org.

Screen Shot 2017-12-31 at 12.36.33.png

Попробовать Perl 6 без загрузки и установки компилятора можно и в онлайне на странице glot.io/new/perl6.

Screen Shot 2017-12-31 at 12.41.07

Люди

В социальной сфере у шестого перла два основных места встречи. Из современного — группа Perl6 на Фейсбуке.

Screen Shot 2017-12-31 at 12.55.25.png

Из прошлой эпохи — IRC-канал #perl6. Я однозначно рекомендую присоединиться к фейсбучной группе, а вот по поводу IRC решайте сами — там, конечно, можно найти интересное или задать вопросы, но при этом много разговоров, которые могут быть не особо интересными.

Что читать в онлайне

Есть сайт pl6anet.org — RSS-агрегатор блогов и сайтов про Perl 6. Ссылки с него появляются и на главной странице perl6.org.

Раз в неделю выходит выпуск Perl 6 Weekly — обзор основных событий за неделю, выходящий обычно вечером по понедельникам. Этого вполне достаточно, чтобы быть в курсе дел.Screen Shot 2017-12-31 at 13.07.06

Если вам интересно следить за деталями разработки компилятора, подпишитесь на рассылки perl6-compiler@perl.org и perl6-language@perl.org. Еще несколько списков вы найдете на странице perl6.org/community в разделе Mailing Lists.

Буквально на днях, видимо как реакция на бурный срачик по поводу изъятия из Perl 5 ключевого слова when, что ломало обратную совместимость, появился ресурс alerts.perl6.org, где на сегодня висит пока единственный алерт про изменение имени метода .parse-names → .uniparse в следующей версии Perl 6.d.

Раз в год, с 1 по 24 или 25 декабря, выходят ежедневные статьи в Perl 6 Advent Calendar. Календарь только что закончился, следующий выход примерно через год, так что не постесняюсь дать ссылку на свой английский блог Perl 6 Inside Out, где я рассказываю о внутреннем устройстве Rakudo Perl 6.

Screen Shot 2017-12-31 at 13.21.26

На perl6.ru тоже заходите 🙂

Книги

Наконец, для офлайнового образования — читайте книги. В 2017 году вышло несколько книг на разный вкус, и еще несколько уже запланировано на 2018-й. Все книги по современному Perl 6 перечислены на странице allperlbooks.com/tag/perl6.0.

Screen Shot 2017-12-31 at 14.06.36.png

На сегодня это все, ждем вас завтра!

Perl 6 XXI века

Недавно на сайте конференции FOSDEM появился анонс: Ларри Уолл объявит, что Perl 6 появится в продакшне в 2015 году. Верить этому или нет, сложно сказать, но я попробовал скачать новый Rakudo и оказалось, что там все заметно лучше (прям сильно лучше), чем было год-два назад.
Поэтому я решил освежить знания про Perl 6 и написал большую статью для Pragmatic Perl «Perl 6 XXI века» с обзором базовых вещей, доступных в языке. Для следующего номера готовится статья о возможностях Perl 6 для параллельных вычислений.

Мероприятия в восточной части Европы до конца года

До конца текущего года состоятся несколько Perl-мероприятий в восточной части Европы.

Во-первых, на 17 октября планируется второй белорусский Perl-воркшоп в Минске.

Во-вторых, на начало декабря готовится второй воркшоп TwinCity — совместное мероприятие Vienna.pm и Bratislava.pm.

В-третьих, 21 ноября в Риге состоится первый в истории балтийский Perl-воркшоп.

Тесты Perl 1

Набор тестов, входящий в состав дистрибутива Perl 1, выполняется Perl 5.10 на 91%.

В книге Masterminds of Programming, в которой собраны интервью с создателями семнадцати языков программирования, я прочитал, как Ларри Уолл заметил, что многие тесты, которые были написаны для первой версии перла, правильно работают и под Perl 5.

Что ж, пробуем.

Дистрибутив Perl 1 доступен на сайте dev.perl.org. В нем есть папка t, в которой находятся около 50 файлов с тестами:

base.cond, base.if, base.lex, base.pat, base.term, cmd.elsif, cmd.for, cmd.mod, cmd.subval, cmd.while, comp.cmdopt, comp.cpp, comp.decl, comp.multiline, comp.script, comp.term, io.argv, io.fs, io.inplace, io.print, io.tell, op.append, op.auto, op.chop, op.cond, op.crypt, op.do, op.each, op.exec, op.exp, op.flip, op.fork, op.goto, op.int, op.join, op.list, op.magic, op.oct, op.ord, op.pat, op.push, op.repeat, op.sleep, op.split, op.sprintf, op.stat, op.subst, op.time, op.unshift

Имена довольно необычны для современных тестов. В добавок в комплекте есть файл TEST, который выполняет роль современной утилиты prove. Сам этот файл работать не хочет, но prove вполне работает:

$ prove *.*

Сводка с результатом работы выглядит так:

Failed 14/49 test scripts. 26/305 subtests failed.
Files=49, Tests=305,  7 wallclock secs ( 1.39 cusr +  0.47 csys =  1.86 CPU)
Failed 14/49 test programs. 26/305 subtests failed.

Из 305 тестов с ошибкой завершились только 26. И это после 20 лет разрабоки языка, невероятно!

Конференц-встречи Хьюстон.pm

Участники Хьюстон.pm экспериментируют с проведением динстанционных встреч группы.

Где бы ни планировалась встреча, из-за географических параметров Хьюстона кому-то все равно будет сложно добираться до места. Решить проблему участники собираются, проводя дистанционные конференц-встречи. Для первой такой встречи они воспользовались услугами сайта dimdim.com.

Конфигурация конференц-связи:

  • 20 бесплатных участников
  • Три одновременно говорящих
  • Наличие общего и приватного чатов
  • Обмен файлами PDF и PPT
  • Обмен ссылками
  • Видимая всем «доска» для одновременного редактирования
  • Поддержка маков и PC

Из отрицательных моментов участники отмечают не лучшее качество звука (возможно, из-за собственных микрофонов) и нарушение синхронизации у одного из участников.

Участники остались довольны и простотой развертывания конференции и рассматривают возможность прводить встречи ежемесячно.