Вы когда-нибудь чувствовали, что большинство языков программирования слишком стараются быть тем, чем они не являются? Как будто они просыпаются утром, смотрят в зеркало и думают: «Сегодня я буду чистым функциональным языком» или «Нет, на самом деле я строго объектно-ориентированный»? Что ж, позвольте познакомить вас с Raku — языком программирования, который посмотрел на все эти правила и решил, что они больше похожи на предложения.

Raku, ранее известный как Perl 6 (да, тот самый Perl), — это то, что получается, когда вы берёте десятилетия опыта работы с Perl, добавляете современные концепции программирования и отказываетесь идти на компромисс в отношении выразительности. Это язык, который позволяет вам писать код так, как вы хотите, будь то использование объектов, функциональное программирование или смешивание всего в хаотичном порядке, который каким-то образом просто работает.

Чем Raku отличается?

Прежде чем мы углубимся в подробности, позвольте задать сцену. Raku — не просто преемник Perl 5, это духовная эволюция, которая идёт своим путём. Когда Perl 5 и Raku разошлись, они стали разными языками. Raku сохранил философию TMTOWTDI (There’s More Than One Way To Do It), но адаптировал её для XXI века.

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

Поддержка Unicode: Raku рассматривает Unicode как первоклассного гражданина. Вы можете использовать греческие буквы в качестве имён переменных, математические символы в своём коде, и язык просто улыбнётся и скажет: «Конечно, почему бы и нет?»

Мощные регулярные выражения и поддержка грамматики: регулярные выражения в Raku не просто мощные — они философские. А если вам нужно проанализировать сложные языки, система грамматики Raku как будто имеет лингвиста в своём углу.

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

Начало работы: установка и ваша первая программа

Давайте перейдём к делу. Чтобы запустить код Raku, вам понадобится Rakudo — наиболее популярная реализация Raku. Думайте о Raku как о спецификации языка, а о Rakudo как о двигателе, который приводит его в действие.

Установка проста. В большинстве систем у вас есть несколько вариантов:

  • Использование Rakudo Star: самый простой путь для новичков. Посетите официальный сайт Rakudo и скачайте предварительно собранный пакет для вашей операционной системы.
  • Использование менеджеров пакетов: если вы используете Linux, в репозиториях вашего дистрибутива, вероятно, есть Rakudo.
  • Сборка из исходного кода: для тех, кто любит рисковать.

После установки откройте терминал и введите:

raku --version

Если вы видите номер версии вместо ошибки, поздравляем — вы в клубе.

Теперь давайте напишем нашу первую программу. Создайте файл с именем hello.raku:

say "Hello, Raku! The language that answers 'yes' to everything.";

Запустите его:

raku hello.raku

Видите? Вы только что освободились от оков соответствия языковым стандартам программирования.

Raku REPL: ваша игровая площадка

Прежде чем мы напишем полноценные программы, освойтесь с REPL (Read-Eval-Print Loop). Это как беседа с Raku. Введите:

raku

Теперь вы в интерактивном режиме. Попробуйте это:

> say 2 + 2
4
> my $name = "Adventurer"
Adventurer
> say "Welcome, $name"
Welcome, Adventurer

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

Переменные и скаляры: строительные блоки

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

Скалярные переменные используют сигил $ и могут содержать практически всё что угодно:

my $age = 42;
my $name = "Jordan";
my $pi_approximation = 3.14159;
my $is_raku_awesome = True;

Декларатор my создаёт лексически scoped переменную. Думайте об этом как о том, что вы говорите: «Эй, Raku, мне нужна коробка, чтобы что-то хранить. Убедись, что никто за пределами этой области видимости не сможет это изменить».

Вы также можете создавать константы:

constant $THE_ANSWER = 42;

Попробуйте изменить её, и Raku даст вам цифровой эквивалент строгого взгляда.

Типы данных: система типов Raku без бюрократии

Вот что приятно: у Raku есть сложная система типов, но она не заставляет вас её использовать. Вы можете быть настолько конкретными или свободными, насколько хотите.

my Int $count = 5;           # Явно целое число
my Str $message = "Howdy";   # Явно строка
my Num $ratio = 0.75;        # Число с плавающей запятой
my Bool $flag = True;        # Булево значение

Но вы также можете просто позволить Raku разобраться:

my $mystery = "Could be anything";  # Тип выводится автоматически

Raku терпелив с вами. Он не будет осуждать.

Управление потоком: принятие решений со стилем

Условные операторы в Raku читаются почти как английский язык:

my $score = 85;
if $score >= 90 {
    say "Отлично! Вы преуспеваете.";
} elsif $score >= 80 {
    say "Отличная работа! Вы разбираетесь.";
} elsif $score >= 70 {
    say "Неплохо. Могло быть лучше.";
} else {
    say "Ого. Может, попробовать ещё раз?";
}

Но Raku также позволяет вам записывать операторы в более естественном порядке с постфиксными условными операторами:

say "Вы сдали!" if $score >= 70;
say "Вы не сдали." unless $score >= 70;

Это читается как простой английский язык, что и является целью.

Циклы бывают нескольких видов:

# Цикл for в стиле C
for my $i (0..9) {
    say "Итерация $i";
}
# Цикл while
my $count = 0;
while $count < 5 {
    say "Счётчик: $count";
    $count++;
}
# Постфиксный цикл
say "Beep boop" for 1..3;  # Запускается три раза

Оператор .. создаёт диапазон. Вы будете использовать его постоянно. Добро пожаловать в Raku.

Функции: когда вам нужно повторно использовать код (но делать это стильно)

Функции в Raku называются подпрограммами, и они объявляются с помощью ключевого слова sub:

sub greet(Str $name) {
    return "Привет, $name! Добро пожаловать на многопарадигмальную вечеринку.";
}
say greet("Alex");

Функции могут иметь ограничения по типу:

sub add(Int $a, Int $b) {
    return $a + $b;
}
say add(5, 3);  # Работает нормально
say add("hello", "world");  # Ошибка типа! Raku останавливает вас до катастрофы.

Вы также можете сделать параметры необязательными со значениями по умолчанию:

sub describe(Str $thing, Str $mood = "excellent") {
    return "$thing is $mood";
}
say describe("Raku");           # Использует значение по умолчанию
say describe("Perl", "legendary");  # Использует предоставленное значение

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

multi sub process(Int $x) {
    return "Обработка целого числа: $x";
}
multi sub process(Str $x) {
    return "Обработка строки: $x";
}
multi sub process(Num $x) {
    return "Обработка числа: $x";
}
say process(42);          # Вызывает версию для целых чисел
say process("hello");     # Вызывает версию для строк
say process(3.14);        # Вызывает версию для чисел

Raku определяет, какую версию вызвать, основываясь на том, что вы передаёте. Это