Донецкий техникум промышленной автоматики

І знову про Perl 6, що таке Rakudo?

Андрій Шитов Керівник відділення в Островок.ру, Амстердам.

Андрій Шитов: Всім добрий день! Мене звати Андрій Шитов. Презентація, яку я вам продемонструю, називається «Rakudo Perl 6, і що з ним можна зробити сьогодні». Її повністю підготував Джонатан Вортінгтон. Відповідно, всі тексти його. Я лише перевів їх для конференції.

Отже, що таке Perl 6? Perl 6 - це спроба створити нову мову програмування на основі існуючого Perl 5.

Спочатку затія була така: взяти всі кращі моменти з Perl 5, перенести їх, відкинути все зайве. Зробити мова більш регулярним, наскільки це можливо. Оскільки творець Perl Ларрі Уолл - лінгвіст, в мову програмування увійшли дуже багато речей, які притаманні людським мовам.

З приводу регулярності - досить складно зробити мову повністю регулярним. Наприклад, неможливо зробити точку, щоб вона означала одне-єдине поняття в мові. Точка може, наприклад, розділяти десяткову і цілу частини в дрібних числах або може означати виклик методу. Проте, в дизайні Perl 6 досить багато регуляризації. У більшості випадків однаковий символ означає одне й те саме.

З приводу лінгвістики. Perl відрізняється від багатьох мов тим, що багато дій можна зробити по-різному, причому це записано в специфікації. Наприклад, якщо на мові Python програмують табуляціями, то на мові Perl програмують знаками пунктуації. Незрозуміло, що краще. Є такий слоган: «Прості речі в Perl робляться просто, а складні можливо зробити хоч якось».

У Perl 6 - я вже згадав про регулярність - в дизайні спочатку з'являються об'єктно-орієнтовані елементи, які повністю були відсутні в Perl 5 і були замінені якимись штучними підходами з використанням хешів. Ще раз повторюється теза про те, що просте робиться елементарно, а складні речі робляться ще більш можливими, ніж раніше.

Perl 5 ніколи не існував у вигляді готової специфікації мови. Специфікація фактично була запрограмована всередині компілятора. Це була єдина реалізація. Вся поведінка Perl, яке ця реалізація забезпечувала, і вважалося реалізацією.

У Perl 6 все не так. До нього спочатку написали специфікацію - дуже багато, кілька мегабайт. В принципі, вона ще не дописана. Вважається, що будь-яку мову, який проходить набір тестів, які описані в цій специфікації, вважається повноцінним і повноправним компілятором Perl 6. Зараз написано близько 40 000 тестів. Якісь реалізації проходять більшу частину цього набору, якісь не проходять взагалі.

Rakudo - це той компілятор, який зараз розвивається найбільш активно. Більш того, в цьому році планують зробити перший реліз. Судячи з усього, його дійсно зроблять в цьому році. Він проходить три чверті всіх існуючих тестів.

Потрібно розуміти, що тести, по-перше, не охоплюють всі, що описано в документації. По-друге, число тестів кожен день зростає. Існують в списку "коммітов" окремі люди, які "коммітов" баги, і люди, які "коммітов" тести, і не програмують сама мова.

Що всередині? Крім Rakudo, існує віртуальна машина під назвою Parrot. Вона була створена близько десяти років тому для мов програмування типу Perl, Python і інших подібних, які вважаються динамічними мовами програмування. В принципі, віртуальна машина зараз існує і у Java, і у .Net. Але коли створювався Rakudo, інші віртуальні машини були ще в зародковому стані, і підтримувати можливості динамічних мов тоді було дуже важко.

Усередині Perl 6 спочатку планувалося написати повністю на самому собі. Частково це вдалося. Тут перший рядок - NQP ( «Not Quite Perl»). Тобто «не зовсім Perl», мається на увазі - не зовсім Perl 6. Це маленьке підмножина мови, на якому вже зараз можливо описувати граматику, яка розбирає синтаксис мови і розбирає програму. Цей NQP, по суті, є вже Perl 6. Чим далі Perl 6 розвиватиметься, тим більше буде можливостей для того, щоб використовувати мову для опису самого себе і для написання компілятора на самому собі.

Другий пункт - Perl 6. Частина якихось функцій вже зараз можливо писати саме на Perl 6. Частина функцій досі пишеться на внутрішньому поданні Parrot - Parrot Intermediate Language. Це зазвичай низькорівневі функції, які для ефективності зручно писати саме на ньому. Ще більш низькорівневі функції пишуться безпосередньо на "Сі".

Ось приклад того, як виглядає фрагмент граматики, яка описує Perl 6 на Perl 6. Наприклад, тут описано пристрій функції <if>. Ця граматика описує token - якесь слово в мові. Написано, що може бути всередині нього. Після блоку коду «elsif» може бути, наприклад, ще один «else» і так далі. В такому дусі описується весь мову. Читати це з незвички досить складно. Проте, все це дуже регулярно і досить однозначно описує всі можливості мови.

Крім того, парсер, який на основі цієї граматики розбирає мова, може виконувати якийсь код. У Perl є блоки BEGIN, які виконуються ще до того, як починає працювати сама програма. Ці блоки можна виконувати безпосередньо під час розбору, дописавши до відповідних правил шматки якогось коду.

Зараз я покажу приклад, як працює разборщик мови. Якщо хтось знайомий з тим, як влаштовані компілятори - компілятори читають слова в мові і на їх основі будують синтаксичне дерево, яке тут називається AST (абстрактне синтаксичне дерево). Наприклад, функція. Дерево в вершинах має функцію «sin (x + y)» (синус, потім сума, потім два аргументи - x і y).

На цьому прикладі: «якщо ікс - 42, то надрукувати якусь рядок». Як працює парсер?

Парсер, власне, намагається зрозуміти, що тут написано. Після того, як він однозначно зрозумів, за що відповідає конкретний фрагмент, він безпосередньо в цей же момент генерує об'єкт всередині дерева і заповнює його необхідними даними. У цій точці він знайшов змінну X і створив в дереві об'єкт, який називається «змінна», у якого є ім'я і посилання на область видимості. Потім знайшлося число.

Зверніть увагу, що слово «if» і оператор «==» поки пропущені, тому що в даний момент ще невідомо, чим вони будуть займатися. 42 - зрозуміло, це число. Тут же створюється число в дереві.

Потім можна обробити «==».

Потім рядок.

Оператор «say». «Say» - взагалі дуже смішний оператор. Смішний в тому сенсі, що з'явився він в Perl 6, а потім «перекочував» назад в Perl 5. В версії 5.10 він став доступний поряд з багатьма іншими змінами. Тим не менше, більшість людей, коли їх запитують: «Які нові функції з Perl 5.10 ви використовуєте?» - згадують тільки оператор «say».

«Say» - це той же «print», який крім того, що виводить рядок, робить ще й новий рядок, тобто «\ n». Три літери, плюс економія на «\ n», плюс можлива економія на лапках, коли не потрібно інтерполювати рядок - така ось мікроекономія. Проте, дуже популярна.

Нарешті, парсер зміг розібрати весь блок коду в фігурних дужках. Все це завершується, в вершині дерева будується вузол для «if».

Побудували дерево.

Наступна фаза компілятора може пройтися по цьому дереву і або згенерувати на його основі якийсь виконуваний код, або просто виконати,

Отже, що таке Perl 6?
Що всередині?
Як працює парсер?
Ви використовуєте?