Andrew Shitov Rakudo Jonathan

Preview:

DESCRIPTION

 

Citation preview

Rakudo Perl 6

Сегодняшние возможности

Perl 6

Что такое Perl 6? Возьмем лучшее из Perl…

Практичность — акцент на решении задачи Мультипарадигменность — потому что не существует единственного подхода к решению всех задач

Лингвистическое влияние — это же язык программирования

Простые вещи просты, а сложные — возможны

Что такое Perl 6? Построим новый Perl-подобный язык, который…

Более регулярен — меньше особых случаев Более читаем и более поддерживаем Более выразителен Более ОО, более функциональный, более декларативный, более параллельный…

Простое — просто Сложное — еще более доступно

Одна спецификация, много реализаций В отличие от Perl 5, для Perl 6 написана спецификация языка

Нет «официальной» реализации Как и в Perl 5, у Perl 6 есть набор тестов

Правильная реализация должна проходить набор тестов

Это некая «исполняемая спецификация» Сейчас около 40 000 тестов

Rakudo

Что такое Rakudo? Наиболее активно разрабатываемый компилятор Perl 6 Реализует значительную часть спецификации Perl 6

(хотя еще есть, над чем работать) Сегодня проходится более 30 000 тестов из набора тестов Perl 6 (правда набор тестов растет )

Сейчас основан на виртуальной машине Parrot В этом году мы планируем как минимум еще одну платформу

Как работает Rakudo Написан на…

NQP (минимальное подмножество Perl 6) Ядро компилятора (грамматика и построение AST), некоторые мета-модели, поиск и загрузка модулей)

Perl 6Большинство встроенных функций и операторов

Parrot Intermediate LanguageНекоторые низкоуровневые фукнции и «клей» (glue)

CДиспетчеры, работа с сигнатурами, кастомизация VM и «клей»

Как работает Rakudo: парсинг Сначала Rakudo разбирает программу Парсер написан на регексах Perl 6

Может находить новые операторы во время разбора Должен сразу выполнять блоки BEGIN

token statement_control:sym<if> { <sym> :s <xblock> [ 'elsif'\s <xblock> ]* [ 'else'\s <else=.pblock> ]?}

Как работает Rakudo: построение AST Когда заканчивается разбор чего-либо (например, инструкции if), запускается action-метод

Он строит абстрактное синтаксическое дерево (Abstract Syntax Tree, AST)

Это представление программы в абстрактом — не зависимом от синтаксиса языка — виде

Большинство action-методов строят сложное ASTиз маленьких фрагментов, которые уже разобраны

Как работает Rakudo: построение AST

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Var.new( :name('$x'), :scope('lexical'))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Val.new( :value('The Answer!'))

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Op.new( :pasttype('call'), :name('&say'), …)

PAST::Val.new( :value('The Answer!'))

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Block.new( … )

PAST::Op.new( :pasttype('call'), :name('&say'), …)

PAST::Val.new( :value('The Answer!'))

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('if'), … )

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Block.new( … )

PAST::Op.new( :pasttype('call'), :name('&say'), …)

PAST::Val.new( :value('The Answer!'))

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: построение AST

PAST::Op.new( :pasttype('if'), … )

PAST::Op.new( :pasttype('call'), :name('&infix:<==>'), …)

PAST::Block.new( … )

PAST::Op.new( :pasttype('call'), :name('&say'), …)

PAST::Val.new( :value('The Answer!'))

PAST::Var.new( :name('$x'), :scope('lexical'))

PAST::Val.new( :value(42))

if $x == 42 { say "The answer!"; }

Как работает Rakudo: генерация кода Берем дерево AST и генерируем внутренний код под целевую платформу

Сегодня на этом этапе мы делаем код только для виртуальной машины Parrot

Акхитектура такова, что в будущем мы сможем добавить другие бекенды

Кроме того, в этом месте последовательности компиляции возможно выполнять фазы оптимизации и анализа программы

Примеры:сегодняшние возможности

Rakudo

Примеры Рассмотрим набор небольших, посведневных программистских задач и для каждой покажем…

код на Perl 6, решающий задачу вывод после запуска

Надеюсь, это хорошее начало для того, чтобы понять новый синтаксис и новые возможности

Покажу крутые фичи Perl 6 Все показанные сегодня примеры работают в Rakudo

say "Hello, world!"

ЗадачаНапечатать «Hello, world!»

Решение

ВыводHello, world!

print "Enter your name: ";my $name = $*IN.get;say "Hi $name!";

ЗадачаПрочитать строку с консоли

Решение

ВыводEnter your name: JonathanHi Jonathan!

loop { print "Enter a number from 1 to 10: "; my $num = $*IN.get; unless 1 <= $num <= 10 { say "Fail!" }}

ЗадачаПроверить, находится ли значение в данном диапазонеРешение 1

ВыводEnter a number between 1 and 10: 3Enter a number between 1 and 10: 42Fail!

loop { print "Enter a number from 1 to 10: "; my $num = $*IN.get; unless $num ~~ 1..10 { say "Fail!" }}

ЗадачаПроверить, находится ли значение в данном диапазонеРешение 2

ВыводEnter a number between 1 and 10: 3Enter a number between 1 and 10: 42Fail!

my @nums = 1, 5, 7, -2, 3, 9, 11, -6, 14;say [+] @nums;

ЗадачаПросуммировать список чиселРешение

Вывод42

my @a = 1, 1, 2, 3, 5, 8;my @b = 9, 4, 1, 16, 36, 25;if [<=] @a { say '@a is sorted' }if [<=] @b { say '@b is sorted' }

Решение

Вывод@a is sorted

ЗадачаПроверить, отсортирован ли список

my @cities = <Moscow Kazan Vladivostok>;for @cities -> $city { say "I've been to $city";}

ЗадачаПройтись по спискуРешение

ВыводI've been to MoscowI've been to KazanI've been to Vladivostok

my %distances = Bratislava => 1084, Stockholm => 442; for %distances.kv -> $city, $distance { say "$city is $distance km away";}

ЗадачаПройтись по ключам и значениям хеша

Решение

ВыводBratislava is 1084 km awayStockholm is 442 km away

my @a = 75, 47, 90, 22, 80;my @b = 61, 77, 94, 82, 60;my @c = 45, 59, 33, 11, 19; if any(@a) >= 60 { say "Some passes in A" }if any(@b) >= 60 { say "Some passes in B" }if any(@c) >= 60 { say "Some passes in C" }

ЗадачаПроверить, есть ли в списке результатов экзаменов хотя бы один, превышающий порогРешение

ВыводSome passes in ASome passes in B

my @a = 75, 47, 90, 22, 80;my @b = 61, 77, 94, 82, 60;my @c = 45, 59, 33, 11, 19; if all(@a) >= 60 { say "All passes in A" }if all(@b) >= 60 { say "All passes in B" }if all(@c) >= 60 { say "All passes in C" }

ЗадачаПроверить, все ли результаты экзаменов в списке превышают порогРешение

ВыводAll passes in B

my @a = 75, 47, 90, 22, 80;my @b = 61, 77, 94, 82, 60;my @c = 45, 59, 33, 11, 19; if none(@a) >= 60 { say "No passes in A" }if none(@b) >= 60 { say "No passes in B" }if none(@c) >= 60 { say "No passes in C" }

ЗадачаПроверить, что ни один из результатов экзаменов в списке не превышает порогРешение

ВыводNo passes in C

my @drinks = <wine beer vodka>;say "Tonight I'll drink { @drinks.pick }";

ЗадачаВыбрать из списка случайный элементРешение

Вывод (результат дожен меняться ;-))Tonight I'll drink vodka

my @competitors = <Tina Lena Owen Peter>;my @order = @competitors.pick(*);for @order { .say }

ЗадачаПеремешать список в случайном порядке

Решение

Вывод (результат дожен меняться ;-))PeterLenaOwenTina

sub greet($greeting, $name) { say "$greeting, $name!";}greet("hello", "masak");

ЗадачаНаписать и вызвать подпрограмму с параметрами

Решение

Выводhello, masak

sub double(Num $n) { 2 * $n }say double(21);say double("oh no I'm not a number");

ЗадачаНаписать подпрограмму, принимающую только число

Решение

Вывод42Parameter type check failed; expected Num, but got Str for $n in call to double

multi double(Num $n) { 2 * $n }multi double(Str $s) { $s x 2 }say double(21);say double("boo");

ЗадачаВызвать нужную мульти-функцию в зависимости от типа аргументаРешение

Вывод42booboo

multi fact($n) { $n * fact($n - 1) }multi fact(0) { 1 }say fact(1);say fact(10);

ЗадачаВычислить факториал (рекурсивно)

Решение

Вывод13628800

sub fact($n) { [*] 1..$n }say fact(1);say fact(10);

ЗадачаВычислить факториал (используя мета-оператор)

Решение

Вывод13628800

sub postfix:<!>($n) { [*] 1..$n }say 1!;say 10!;

ЗадачаДобавить новый оператор факториала (чтобы работало 10!)

Решение

Вывод13628800

class Product { has $.name; # Атрибут + аксессор has $!price; # Только атрибут has $.discount is rw; # Атрибут + lvalue-аксессор method get_price { return $!price - $!discount; }}

ЗадачаОбъявить класс с атрибутами и методами

Решение

my $prod = Product.new( name => "Beer", price => 500, discount => 60);say $prod.get_price;

ЗадачаСоздать экземпляр класса и вызвать на нем метод

Решение

Вывод440

say $prod.name;$prod.discount = 40;say $prod.get_price;$prod.name = 'Wine';

ЗадачаПрочитать/записать атрибут через аксессор

Решение

ВыводBeer460Cannot assign to readonly variable.

my @products = Product.new(name => 'Beer', price => 500), Product.new(name => 'Wine', price => 450), Product.new(name => 'Vodka', price => 1600);my @uc_names = @products>>.name>>.uc;for @uc_names { .say }

ЗадачаВызвать метод на каждом объекте из списка

Решение

ВыводBEERWINEVODKA

my @meths = Product.^methods(:local);for @meths>>.name { .say }

ЗадачаСделать интроспекцию, чтобы узнать методы класса

Решение

Выводget_pricediscountname

my @products = Product.new(name => 'Beer', price => 500), Product.new(name => 'Wine', price => 450), Product.new(name => 'Vodka', price => 1600);my @sorted = @products.sort(*.name);for @sorted { .name.say }

ЗадачаОтсортировать список объектов с учетом вызова метода

Решение (пример 1)

Вывод (пример 1)BeerVodkaWine

my @products = Product.new(name => 'Beer', price => 500), Product.new(name => 'Wine', price => 450), Product.new(name => 'Vodka', price => 1600);my @sorted = @products.sort(*.get_price);for @sorted { .name.say }

ЗадачаОтсортировать список объектов с учетом вызова метода

Решение (пример 2)

Вывод (пример 2)WineBeerVodka

my @temperatures = -3, 5, 7, 2, -1, -4, 0;say "Minimum was " ~ @temperatures.min;say "Maximum was " ~ @temperatures.max;

ЗадачаНайти минимальное и максимальное значения в списке

Решение (пример 1)

Вывод (решение 1)Minimum was –4Maximum was 7

my @products = Product.new(name => 'Beer', price => 500), Product.new(name => 'Wine', price => 450), Product.new(name => 'Vodka', price => 1600);say "Cheapest: " ~ @products.min(*.get_price).name;say "Costliest: " ~ @products.max(*.get_price).name;

ЗадачаНайти минимальное и максимальное значения в списке

Решение (пример 2)

Вывод (пример 2)Cheapest: WineCostliest: Vodka

class Paper { }class Scissor { }class Stone { }multi win(Paper, Stone) { "Выиграл" }multi win(Scissor, Paper) { "Выиграл" }multi win(Stone, Scissor) { "Выиграл" }multi win(::T, T) { "Ничья" }multi win(Any, Any) { "Проиграл" }

ЗадачаРеализовать игру «Камень, ножницы, бумага»

Решение (часть 1)

say win(Paper, Paper);say win(Scissor, Stone);say win(Stone, Scissor);

ЗадачаРеализовать игру «Камень, ножницы, бумага»

Решение (часть 2)

ВыводНичьяПроигралВыиграл

Rakudo *[Ракудо стар]

Что такое Rakudo *? Заметный прогресс Rakudo

Постоянно реализуются новые части спецификации Постоянно растет число пройденных тестов Исправляется много багов Растет число активных разработчиков

До сих пор мы фокусировались на процессе создания Rakudo

Rakudo * — релиз, где мы фокусируемся на том, что нужно первопроходцам

Что войдет в релиз? Мы делаем релиз компилятора каждый месяц;а Rakudo *, напротив, — дистрибутив, включающий:

Компилятор Rakudo, конечно же Инструмент для загрузки, установки и обновления модулей

Набор модулей Perl 6 для решения типовых задач (например, HTTP-клиент и сервер, соединение с базой данных, что-нибудь для веба, YAML…)

Что войдет в релиз? Мы намереваемся включить пару других проектов…

Zavolaj! — модуль, позволяющих писать на Perl 6 обертки для библиотек C; на нем мы сделали клиент MySQL

Blizkost — промежуточный слой Perl 5 Parrot, котоырй позволит из Perl 6 использовать модули Perl 5

Что Rakudo * будет делать хорошо Rakudo хорошо покрывает большую часть спецификации Perl 6…

Широкий выбор встроенных операторов, типов и функций Подпрограммы, сигнатуры и множественная диспетчеризация

ООП, включая классы, роли, интроспекцию и многое другое

Perl 6 регексы и грамматики (именно ими мы делаем разбор Perl 6!)

Слабые места Rakudo * сможет многое предложить и окажется полезным для многих задач

Однако, это не полный Perl 6, и, конечно, с недостатками, например:

Отсутствие поддержки тредов Отсутсвие поддержки нативных типов Довольно медленный — еще не все оптимизировано, и отсутствует оптимизатор

Когда? Скоро

Когда? Скоро Или в конце мая, или в начале или середине июня

Когда? Скоро Или в конце мая, или в начале или середине июня Да, в этом году

Вливайтесь!

Как узнать больше? Загрузите Rakudo Perl 6 с сайта

http://www.rakudo.org/ Много ссылок на ресурсы про Perl 6 собрано на сайте

http://www.perl6.org/ Присоединяйтесь к дружелюбному IRC-каналу

#perl6 on irc.freenode.org Пишите модули, создавайте приложения, включайтесь в развите сообщества Perl 6 и делайте свой вклад в него

Спасибо

Вопросы?

Recommended