View
424
Download
0
Category
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