Perl 6 — мультипарадигменный язык. Это означает, что на нем можно писать в разных стилях, как минимум в процедурном, в ООП- и в функциональном.
Сегодня мы посмотрим, как можно организовать рекурсию для простейшей задачи — печати чисел от 1 до 10.
Сразу оговоримся, что простейшее решение этой задачи такое:
.say for 1..10;
Но на этом примере попробуем понять, как задействовать механизмы Perl 6, чтобы сделать рекурсивный код.
Самое примитивное — вызвать функцию из самой себя и в нужный момент остановиться; здесь нет ничего нового:
gen-number(1, 10); sub gen-number($current, $maximum) { say $current; gen-number($current + 1, $maximum) if $current < $maximum; }
Возможно, стоит отметить, что если выбран функциональный стиль программирования, то следует отказаться от явного изменения переменных, так что следующий вариант (идеологически) не подходит:
my $current = 1; my $maximum = 10; while $current <= $maximum { say $current; $current++; # $current = $current + 1 }
А вот теперь новое. Perl 6 позволяет переопределять функции, причем он может выбрать подходящий вариант не только по числу или типу аргументов, но и по их значению. Вот пример того, как отказаться от конечного условия в оригинальной функции:
gen-number(1, 10); multi sub gen-number($current, $maximum) { say $current; gen-number($current + 1, $maximum); } multi sub gen-number($current, $maximum where {$current == $maximum}) { say $current; }
Функция gen-number теперь объявлена мультифункцией. Второй вариант ограничивает свои аргументы: они должны быть равны, чего требует условие со словом where. Поэтому в первых девяти случаях будет вызван первый вариант, и только когда $current сравняется с $maximum, сработает второй вариант функции, которая лишь печатает значение, но не продолжает рекурсию.
Эм… Слушай, по поводу прерывания рекурсии через мультиметод… У меня этот способ не работает, по крайней мере, когда я его пишу в командной строке Windows.
Да, я не очень понимаю в чём дело. Например, пример с проверкой на длину вводимой строки, которая синтаксически выглядела практически точно так же, работает как надо. Причина ли в компиляторе, в её работе на винде, или в чём-либо ещё?
А версия какая? perl6 -v
This is Rakudo Star version 2017.10 built on MoarVM version 2017.10
implementing Perl 6.c.
А что за ошибка?
Да не, ошибки никакой нет, точнее мне отсчета об ошибки не приходит. Просто рекурсия не прерывается при достижении максимального числа, если работать через cmd.
Сейчас только что проверил работу кода на онлайн ресурсе (https://glot.io/new/perl6), и там он работает как положено.
Да, реально из REPL не работает.