3. Мультифункции для рекурсии в Perl 6

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, сработает второй вариант функции, которая лишь печатает значение, но не продолжает рекурсию.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s