Upgrade to Pro — share decks privately, control downloads, hide ads and more …

プログラミング言語処理系を自作してわかったこと

takesako
August 04, 2012

 プログラミング言語処理系を自作してわかったこと

ソフトウェア工学の古典「人月の神話」の「セカンドシステム症候群」によると、
二度目にデザインするシステムは、初回で実装を見送った要求を詰め込み過ぎて失敗作になりやすく
なるため、適切な取捨選択が重要であると言われています。
これはプログラミング言語のデザインや実装にも適用される話なのでしょうか?
本セッションでは、過去に何度もプログラミング言語をデザインし実装し続けている
経験豊富な方々と、今回初めて言語処理系を自分で作ってみた方々の両方をお招きし、
現代的なプログラミング言語処理系のデザインと実装の課題についてディスカッションを行います。

takesako

August 04, 2012
Tweet

More Decks by takesako

Other Decks in Programming

Transcript

  1. LIGHTWEIGHTLANGUAGEDECADE 【問題1】何をするプログラムでしょうか? 入力A < input #!perl -p0 s+¥.+map/¥e/g,$`.82/341x3^($^x3).$_+eg ................[LF] ................[LF]

    ..*.............[LF] ................[LF] ................[LF] ................[LF] ......*.........[LF] ................[LF] 出力A > output 0000000000000000[LF] 0111000000000000[LF] 01*1000000000000[LF] 0111000000000000[LF] 0000000000000000[LF] 0000011100000000[LF] 000001*100000000[LF] 0000011100000000[LF]
  2. LIGHTWEIGHTLANGUAGEDECADE 【問題1】何をするプログラムでしょうか? 入力B < input #!perl -p0 s+¥.+map/¥e/g,$`.82/341x3^($^x3).$_+eg ................[LF] ................[LF]

    ....***.....***.[LF] ...**.*....**.*.[LF] ..**......**....[LF] ...*****...*****[LF] ...*.*.*...*.*.*[LF] ...*.***...*.***[LF] 出力B > output 0000000000000000[LF] 0001232100012321[LF] 0013***20013***2[LF] 013**5*2013**5*2[LF] 01**654311**6543[LF] 014*****214*****[LF] 003*7*8*303*7*8*[LF] 002*4***202*4***[LF]
  3. LIGHTWEIGHTLANGUAGEDECADE 【解説】マジックナンバー 82/341 って何? #!perl -p0 s+¥.+map/¥e/g,$`.82/341x3^($^x3).$_+eg 割り算で 111 が並ぶ

    17byte の文字列を生成 する 98/880: 0.111363636363636 (17byte) 99/888: 0.111486486486486 (17byte) 37/997: 0.037111334002006 (17byte) 83/881: 0.094211123723042 (17byte) 77/934: 0.082441113490364 (17byte) 82/341: 0.240469208211144 (17byte)
  4. LIGHTWEIGHTLANGUAGEDECADE Perl 5 “Hello, world!” package Earth;sub Greet{ %_=('Y','~');$_='$;=!(Middle Earth.age~~~<Eart~~~~~~~~~~~~~h

    .age)?!(defined$ti~~~~~~~~~~~mez~~~On e[2])?!(push@time~~~~~~~~~~~~~~~~Zone,loc ~altime())?rotation?~~~~~~~~~~~~~q~~?The Worl ~~d?:q:[¥w]::q=[¥~~~~~~~~~~~~~~~~~d~a-f]=:q?..~~ ~~~?:q:.:;"42b3d3~~~~~~~~~~~~~~~~~~~~~728656c6c6f6 ~~~~~0277f627c64672~~~~~~~~~~~~~~~~~~~~~b3072796e647 ~~~~~~~42b3b3rg7d"=Ym~~~~~~~~~~~~~~~~~~~¥$;~~*¥;p~~~~u ~~~~~~~~~sh@_,$&;bless~~~~~~~~~~~~~~~~~~~~~~~~~$c~~~~~~~ ~~~~~~~~~o~ntine~~~~~nt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~s=¥~~~~~~~$~~~~~~~~~~~~~~~~~~~~~~~pangaea~~~~ ~~~~~~~~~~~~~~~;{l~~~~~~~~~~~~~~~~~~~~~~~~~~~~ocal@_;local$; ~~~~~~~~~~~~~~~~~="o~~~~~~~~~~~~~~~~~~~~~~~~~cean";$^A=(defi ~~~~~~~~~~~~~~~~~~~n~~~~~~~~~~~~~~~~~~~~~~~~~ed$continents)? ~~~~~~~~~~~~~~~~~~~(vec(~~~~~~~~~~~~~~~~~~~~~~$;, YYsplit(¥' ~~~~~~~~~~~~~~~~~¥',${¥$;}~~~~~~~~~~~~~~~~~~~~~~)%3,YYsplit( ~~~~~~~~~~~~~~~~q??,$;)**2-~~~~~~~~~~~~~~~~~~~~~~(($;=Ytr/oa ~~~~~~~~~~~~~~~~eiu//)**2))=~~~~~~~~~~~~~~~~~~~~~~=28160)?q: ~~~~~~~~~~~~~~~~~.::q?!?:¥'?~~~~~~~~~~~~~~~~~~~~~~¥';}$^A=Ys ~~~~~~~~~~~~~~~~:¥Q.¥E:pack(~~~~~~~~~~~~~~~~~~~~~~¥'h*¥',j ~~~~~~~~~~~~~~~~~oin(q(),~~~~~~~~~~~~~~~~~~~~~~~grep{$_= ~~~~~~~~~~~~~~~~~~Ym,$,,}~~~~~~~~~~~~~~~~~~~~~~~split(" ~~~~~~~~~~~~~~~~~",@_~~~~~~~~~~~~~~~~~~~~~~~~~~[0])) ~~~~~~~~~~~~~~~~):e~~~~~~~~~~~~~~~~~~~~~~~~~~~gexe ~~~~~~~~~~~~~~~;$d~~~~~~~~~~~~~~~~~~~~~~~~~~~="s ~~~~~~~~~~~~~~ort~~~~~~~~~~~~~~~~~~~~~~~~~~<= ~~~~~~~~~~~~>,~~~~~~~~~~~~~~~~~~~~~~~~~~YY ~~~~~~~~~~~@_~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~"~~~~~~~~~~~~~~~~~~~';; s,(~|¥r|¥n|¥s),,g;s.Y.¥x7e.g; eval};Greet;'the world'; http://www.perlmonks.org/index.pl?node_id=329174 by jbware on Feb 15, 2004 at 21:08 UTC (#329174=obfuscated)
  5. LIGHTWEIGHTLANGUAGEDECADE Perl6 言語仕様 (language specification) 1. Apocalypse(黙示録)  Larry Wall

    が Perl6 のデザインについて語る  Perl6 の歴史的な文書(33個のRFCがベース) 2. Exegesis(注釈)  Perl6 を用いたサンプルコードや Perl5 との比較  黙示録を Damian Conway が詳細に解説 3. Synopsis(概要)  Perl6 の最新の言語仕様が書かれている  黙示録のダイジェスト版
  6. LIGHTWEIGHTLANGUAGEDECADE Why Perl 6 ? (モチベーション) Perl 5 は・・・ 場当たり的な拡張を繰り返し

    既に Perl5 のコードは理解不能な領域に C でゴリゴリ 職人技 (needs more C hacker) Perl 6 の目指す方向 せめて OO らしく 他の言語で良いところは取り入れよう 後方互換性は無視 コンパイラと実行環境の分離 Parrot で VM 化 No more C hacker
  7. LIGHTWEIGHTLANGUAGEDECADE 救世主 Pugs の登場 Pugs = Perl6 User’s Golfing System

    Yet another Perl6 implementation → Perl6 が動いた! 2005/02/06 (1|2)+(3|4)→(4|5|6)
  8. LIGHTWEIGHTLANGUAGEDECADE 5秒でわかる Perl 6 メソッドを -> ではなく . で書けるように なった

    Perl 5 $obj->method(); Perl 6 $obj.method(); → これで Perl も立派なOO言語の仲間入り!
  9. LIGHTWEIGHTLANGUAGEDECADE 配列とハッシュのアクセス方法が変更 はじめての人にもわかりやすく 変数のプレフィクス $@% ルールが変更 Perl5 Perl6 my @array

    = (1, 2, 3); my %hash = ('a'=> 1); # 配列のメンバにアクセス my $x = $array[0]; # ハッシュのメンバにアクセス my $y = $hash{'a'} my @array = (1, 2, 3); my %hash = ('a'=> 1); # 配列のメンバにアクセス my $x = @array[0]; # ハッシュのメンバにアクセス my $y = %hash{'a'}
  10. LIGHTWEIGHTLANGUAGEDECADE Perl 6 で失ったもの ~後方互換性~ 文字列の連結 .(ドット)→ ~(チルダ)に Perl5 #

    メソッド呼び出し $obj->method(); sub func { return "x"; } # 文字列の連結 my $a = "str"; my $b = $a.func(); Perl6 一時期 ” _ ” という案もあったが…スペース入れるのが面倒 # メソッド呼び出し $obj.method(); sub func { return "x"; } # 文字列の連結 my $a = "str"; my $b = $a~func();
  11. LIGHTWEIGHTLANGUAGEDECADE () 括弧省略 if, for, while, do ブロックでの(括弧省略) キータイプの量が少なくなった Perl5

    Perl6 if ($a eq $b) { print "a=b¥n"; } while ($i > 0) { $i--; } if $a eq $b { say "a=b"; } while $i > 0 { $i--; }
  12. LIGHTWEIGHTLANGUAGEDECADE Piping operators(<==, ==>) Perl6 @result = map { floor($^x

    / 2) } grep { /^ ¥d+ $/ } @data; @result <== map { floor($^x / 2) } <== grep { /^ ¥d+ $/ } <== @data; @data ==> grep { /^ ¥d+ $/ } ==> map { floor($^x / 2) } ==> @result;
  13. LIGHTWEIGHTLANGUAGEDECADE Parrot Parrot Assembler (PASM) PASM set I1, 33 set

    I2, 5 mod I3, I1, I2 if I3, REMA print "5 is an integer divisor of 33" branch DONE REMA: print "5 divides 33 with remainder " print I3 DONE: print "¥n" end 33÷5=6、余り2 を計算する (5 into 33 is 6, remainder 2)
  14. LIGHTWEIGHTLANGUAGEDECADE Perl 6 cheat sheet »ö« SIGILS MAJOR/MINOR CONTEXTS ACCESS

    ARRAYS HASHES $scalar item list sink whole: @array[] %hash{} @array Str flat/lol element: @array[0] %hash{'a'} %hash Num lazy/eager/hyper (or) %hash<a> &code Bool slice: @array[0,2] %hash{'a','b'} COMPOSERS (or) %hash<a b> TWIGILS [ ] array $normal-lexical { } block/hash AUTOMATIC DEREFERENCE $?compiler-constant < > quotewords &($foo)(1,2) == $foo(1,2) $*dynamic-or-global (,) parcel @($foo)[1] == $foo[1] $.public-accessor :() signature %($foo){'bar'} == $foo<bar> $!private-attribute ¥() capture @(@($foo)[1])[2] == $foo[1][2] $^positional-param $:named-parameter CONTROL SYNTAX $=pod-info for LIST { } # implicit $_ arg $<named-match-capture> for LIST -> $a, $b { } # explicit args $~slang-variable while/until EXPR { } repeat while/until EXPR { } # do at least once OPERATOR PRECEDENCE loop { } loop (a;b;c) { } # parens required! .method .[] i if EXPR { } elsif EXPR { } else { } ++ -- unless EXPR { } # no else allowed! ** given EXPR { when EXPR { } default { } } unary + - ~ ! ? ^ EXPR if EXPR for LIST; # list comprehension
  15. LIGHTWEIGHTLANGUAGEDECADE Perl 6 cheat sheet »ö« * / % %%

    div next, last, redo # loop controls + - proceed, succeed # switch controls x xx TYPES ~ Bool Bit Int Rat FatRat UInt Num Complex int32 complex64 etc. & Str Cat Blob Char Byte Codepoint Grapheme Buf buf8 buf32 utf8 | ^ IO Mu Any Cool Junction Whatever Match sleep abs sin temp Parcel Capture Signature <=> leg cmp .. but SCOPE DECLARATORS Pair Range Set Bag ~~ > == gt eq === eqv !op my lexical scope KeyHash KeySet KeyBag && our package scope Scalar Array Hash Code || ^^ // min max has instance scope Enum Order TrigBase ??!! ff anon no scope at all Block Routine Sub = := op= => state persistent lexical Method Regex so not augment benign parasitic Failure Exception , : supersede deadly parasitic Instant Duration X Xop Z Zop ... Date DateTime say die map etc. OPERATOR DOMAINS and Numeric: == !==(!=) + < > <=> <= >= or xor Stringy: eq !eq(ne) ~ lt gt leg le ge <== ==> Value: eqv !eqv before after cmp !after !before ObjectID: === !===
  16. LIGHTWEIGHTLANGUAGEDECADE Perl 6 cheat sheet »ö« METAOPERATORS LINKS IRC [op]

    reduce listop to A op B op C... perl6.org #perl6 irc.freenode.net op= A = A op B rakudo.org #parrot irc.perl.org !op !(A op B) »op« hyper/vectorize REGEX METACHARS REGEX MODIFIERS Zop zip with op ^ $ string begin/end :i ignore case Xop cross with op ^^ $$ line begin/end :m ignore marks Rop reverse args + one or more :g global Sop sequentialize * zero or more :r ratchet ? zero or one :s sigspace SPECIAL VARIABLES **1..3 repeat in range :4th nth occurrence $_ current topic () capture to $0,$1 :4x n times $/ regex result [] no capture $! error object <foo> subrule REGEX CHARCLASSES @*ARGS command line <[]> character class . == anychar, ¥N non ¥n @*INC include path | parallel or ¥s == <space>, ¥S non %*ENV environment || serial or ¥d == <digit>, ¥D non $*PID process id « » word boundary ¥w == <+alpha+digit+[_]>
  17. LIGHTWEIGHTLANGUAGEDECADE Second System Syndrome (The Mythical Man-Month)  2度目にデザインするシステ ムは失敗作になりやすい説

     1度目のデザインは自分の能力 を把握していないので慎重に  3度目のデザインは何が普遍的 で何が特殊なものか分かるので 正確に作ることができる  しかし2度目のデザインでは、 最初のデザインで抑えたアイデ ア・装飾を思い切り詰め込んで しまうので失敗作になりやすい 人月の神話―狼人間を撃つ銀の弾はない ISBN: 4894716658 → Perl6 は構想10年!