Mercurial > hg > Events > OSC2019
view slide.md @ 13:4d2d4c086913
add poster pdf
author | tobaru |
---|---|
date | Fri, 19 Apr 2019 19:10:17 +0900 |
parents | d8feb607c44e |
children | 642787982a80 |
line wrap: on
line source
title: Perl6の内部表現 author: Takahiro Shimizu profile: lang: Japanese ## このセッションの内容 - Perl6の主要な実装であるRakudoの内部構造を探ります - Rakudoの内部で利用されているVMや, Perl6のサブセットなどについて探索します - スクリプト言語で主に使われているバイトコードインタプリタの気持ちになります ## Perl6とは - 当初Perl5の時期バージョンとして開発されていたプログラミング言語 - 仕様と実装が分離しており, 現在はテストが仕様となっている - 実装は複数存在しているが,現在主流な実装はRakudoとなっている - 言語的にはスクリプト言語であり, 漸進的型付き言語となっている - MoarVM, JVMで動作する <img src="2000px-Camelia.svg.png" alt="" style="width: 31%; height: auto;"> ## Perl6のソースコード概要 - Perl5の文法とは比較的変更が多い - 変数がオブジェクトと化した事により, 変数からsayメソッドを呼ぶことが可能 ``` my $str_value = 'hello world!'; $str_value.say; # hello world! ``` - Perl5と同様に,変数にはデフォルトでは型がないような振る舞いをする ``` my $sample_value = 'hello world!'; $sample_value.say; # hello world! $sample_value = '31'; $sample_value.say; # 31 say($sample_value * 3); ``` ## Perl6の言語的な特徴 - 漸進的型付き言語である為, 型を強制することも可能となる ``` my Int $int_value = 31; $int_value = "hello"; # Compile error! ``` ``` $ perl6 type_invalid.p6 Type check failed in assignment to $int_value; expected Int but got Str ("hello") in block <unit> at type_invalid.p6 line 4 ``` ## Perl6の言語的な特徴 - 型を独自に定義することも可能 - 入力の型によって実行する関数を変える事などができる ```perl6 my subset Fizz of Int where * %% 3; my subset Buzz of Int where * %% 5; my subset FizzBuzz of Int where Fizz&Buzz; my subset Number of Int where none Fizz|Buzz; proto sub fizzbuzz ($) { * } multi sub fizzbuzz (FizzBuzz) { "FuzzBuzz" } multi sub fizzbuzz (Fizz) { "Fizz" } multi sub fizzbuzz (Buzz) { "Buzz" } multi sub fizzbuzz (Number $number) { $number } fizzbuzz($_).say for 1..15; ``` ## スクリプト言語処理系 - スクリプト言語は入力として与えられたソースコードを、 直接評価せずにバイトコードにコンパイルする形式が主流となっている - その為スクリプト言語の実装は大きく2つで構成されている - バイトコードに変換するフロントエンド部分 - バイトコードを解釈する仮想機械 <img src="fig/bytecode_sample_generally_lang.svg" width="80%"> ## Perl6の処理系の構成 - Perl6の処理系は現在はRakudoと呼ばれる(歴史上複数存在する) - Rakudoは3つのレイヤーから構成されている - Perl6インタプリタ - Perl6インタプリタを記述するPerl6のサブセットNQP - Perl6のバイトコードを解釈するMoarVM - このうちPerl6インタプリタとNQPはNQP自身で記述されている - MoarVMはC言語で記述されている ## Perl6とNQP - NQP(NotQuitPerl Perlっぽい別の言語)でRakudoを記述している - NQPもNQPで記述されている為、 セルフビルド(自分自身で自分自身をコンパイルする)を行う - NQPはPerl6の文法をベースにしているが、 制約がいくつか存在する ``` #! nqp sub fib($n) { $n < 2 ?? $n !! fib($n-1) + fib($n - 2); } my $N := 29; my $t0 := nqp::time_n(); my $z := fib($N); my $t1 := nqp::time_n(); nqp::say("fib($N) = " ~ fib($N)); nqp::say("time = " ~ ($t1-$t0)); ``` ## プログラミング言語とVM - 最近のスクリプト言語は、 ソースコードを直接解釈せず、バイトコードに変換しVMが評価する - 全体的な処理速度の向上の為 - 実装を分離することでの見通しの良さ - 言語処理系の実行にのみ動作するVM(プロセスVM) - 他言語の環境 - Java - JVM - Ruby - YARV - Python - PythonVM - Elixir - BEAM ## Perl6のVMの構成 - MoarVMと呼ばれるVM - C言語で記述されている - レジスタマシン - 型情報を持つレジスタに対しての演算として処理される - LuaJITなどを利用したJITコンパイルなども可能 - Perl6やNQPは、MoarVMに対してライブラリなどを設定して起動する ## バイトコード - Perl6も、Rakudo/NQPはバイトコードに変換され、 バイトコードをVMが実行する - バイトコード実行部分は、 命令に対応するバイト列を読み込み、 解釈し、 次の命令を読み取ることを繰り返す