モダンPerlの世界へようこそ

第14回Rakudo:実装する方法だってひとつではないのです

2010年4月に出るのは……

先日、いわゆるPerl 6の実装が2010年4月をめどにRakudo *(Rakudo Star)の名前でリリースされる、という記事が紹介されました。

そのネタ元となった記事を書いたパトリック・ミショー(Patrick Michaud)氏は、2009年4月17日のNordic Perl Workshopを皮切りに、2009年6月22日のYAPC|10(YAPC::NA⁠⁠、2009年7月22日のOSCON2009年8月4日のYAPC::EUと、立て続けにRakudoの発表を行い、そのまとめとして当該記事を掲載したのですが(ちなみにRakudo *の公開時期はすでにOSCONの時点で明言されていました⁠⁠、その3日後にご本人によるフォロー記事が出ているように、この短い紹介記事では意図が伝わりにくい面もあったようです。

そこで、今回はRakudoとはどのようなもので、今回の発表がどんな意味を持つものだったのか、もう少し踏み込んだ説明をしてみようと思います。

Perl 6に至るまでの道のり

Perlは、もともとはawkやsedを駆使するシェルスクリプトとCのいいとこ取りを目指して生まれた言語でした。もちろん最初からそれほど多くのことができたわけではありませんが、その懐の深さから、1994年にPerl 5が出るまでには実に多くの機能が取り込まれてきましたし、Perl 4時代には少なからぬ数の分岐が存在していました。昔からのユーザであれば、日本人向けにマルチバイト処理を追加したjperlだけでなく、oraperlのようにデータベース固有のライブラリを加えたPerlなどがあったことも覚えておられることでしょう。

Perl 5では、このような状況を整理し、本体に新しい機能を追加するのではなく、外部モジュールを使って機能を拡張する方向に舵を切ります。その方針変更は非常にうまくいき、CPANはいまや7000人を越す作者が18000以上のディストリビューション、7万以上のモジュールを登録する巨大なネットワークに成長しましたが、たとえばスレッドやUnicode対応のように、本体に影響を与えるような修正が必要になる場面はまだ残っていました。そして、Perl本体のソースコードは複雑になりすぎて、何かを壊さずには新しい機能を追加できないような状態になっていました。

そこで、一度現在の実装については忘れて、次世代のPerlにふさわしい仕様を書くところから仕切り直そう、という話になったのが、Perl 6プロジェクトの発端でした。それが2000年のことだったのは、この連載でも何度か出てきた通りです。

その後、紆余曲折を経て、Apocalypse(黙示録)やExegesis(釈義⁠⁠、そしてそれらをわかりやすく書き直したSynopsis(梗概)といった基本仕様が一通り出揃ったのが2004年のこと。翌2005年にはその仕様をもとに、オードリー・タン(唐鳳)氏が覚えたてのHaskellを使ってPugsと呼ばれる処理系を実装します。

Pugsがもたらしたもの

PugsはPerl 6の世界にさまざまなものをもたらしました。たとえば、Pugsそのものをテストするために大量のPerl 6コードが書かれたおかげで、まだ議論が尽くされていない仕様の漏れや、無理矛盾が指摘されるようになりましたし、実際に手を動かして試せる環境ができたことで、直接仕様の策定にかかわっていなかった開発者を引き込むこともできるようになりました。2005年5月には早くもIRC上で会話しながら実際にPerl 6のコードを試せるように、Perl 6製のevalbotが登場していますし、⁠現在は利用できないようですが)2006年にはブラウザ上からPerl 6のコードを試せるようにWeb端末も用意されていました。Pugsのリポジトリには、いくつかのCPANモジュールの移植が試みられた痕跡も残っています。

要するに、いわゆる「Perl 6」は、仕様にしても、実装にしても、このときすでにあったわけです。

ただ、当時でさえPerl 1.0時代から数えて17年、Perl 5.0から数えても10年の蓄積があった現行の処理系に比べると、実装が始まったばかりのPugsはあきらかに足りないものだらけでした。そんな状態でうかつに「Perl 6が出た」と言っては、いたずらにPerl 6の評判を落とすだけです。

だから、誰もが口をぬぐって「⁠⁠みんなが満足するような)Perl 6はいつかのクリスマスに」という話を繰り返しました。PugsがHaskellで書かれていたことも、その言い訳がもっともらしく聞こえる一因となったのでしょう。誰もが、プロトタイプでない、オフィシャルな「Perl 6」は別にあるはずだと思っていました。その根拠となったのが、Parrotという(言語向け)仮想マシンの存在でした。

瓢箪から駒

Parrotは、もともとは2001年の壮大なエイプリルフールのネタでした。詳しい顛末は仕掛け人であったサイモン・カズンズ(Simon Cozens)氏の記事をご覧いただくとして、簡単にいうと、Parrotは「Perl 6の設計に取り組んでいたPerl業界と、Python 3000の設計に取り組んでいたPython業界が、手に手を取り合って生み出した新しいP言語」という楽しい空想、のはずだったのです。

ところが、プログラミング言語を実装するための技術はこの数十年来大きく変わっていないことから、ベストプラクティスをまとめた汎用的な仮想マシンを用意すれば、Perl 6の実装に役立つだけでなく、将来的には(ネタにあがった)Pythonをはじめとする、ほかの言語の(再)実装にも役立つだろう、という見通しのもと、2001年9月には本当にParrotという仮想マシンのバージョン0.0.1がリリースされてしまいます。

以来、Parrotはさまざまな企業・団体の助成金を受けながら、2009年3月にバージョン1.0までたどり着き、いまは2010年に予定されているバージョン2.0目指して、月に1回、第3火曜日にリリースが続けられています(2009年8月18日には「TEH PARROTZ!」という名前のバージョン1.5.0がリリースされました⁠⁠。

Perl 6でPerl 6を

そのParrotのリポジトリのなかには、ほかのさまざまな言語のリポジトリとともに、Perl 6という名前のリポジトリがありました。

このPerl 6 on Parrotの実装は、ミショー氏が関与した正規表現まわりなど、一部の機能についてはPugsを上回る出来を見せていたものの(実際、Pugsは2006年9月に自前のツールを用意するまで、このParrotの正規表現解析器を利用していました[1]⁠、全体的な開発のペースは当初期待されていたほど良好なものではありませんでした。

もちろんそこにはParrot側の実装の遅れといった問題もあったのですが、おそらくそれと同じくらい切実だったのが、Perl 5の開発言語であるC(や、そのマクロ集であるXS)を書ける開発者の数に比べて、Parrotの内部表現に通じている開発者の数が圧倒的に少なかったことでした(HaskellベースのPugsもまったく同じ問題を抱えていました⁠⁠。

この問題を緩和するため、2007年にはPugsから派生したKindaPerl6(⁠⁠Perl 6的ななにか⁠⁠)や、Perl 6 on Parrotから派生したNot Quite Perl 6(⁠⁠あまりそれっぽくないPerl 6⁠⁠)など、Perl 6を実装するためのソースコード自体をPerl 6で記述するための、機能を限定したPerl 6の実装が立て続けに登場します。Perl 6 on Parrotの大部分は、このNot Quite Perl 6を利用して書き直されました。

ただ、このように実装が乱立すると、どうしても「開発リソースを一箇所に集中してさっさと『Perl 6』を完成させるべきだ」という議論が出てきます。

2008年1月に登場したRakudoは、ある意味ではその問題を解決するために生まれたといってもよいのかもしれません。

RakudoとPerl 6

もっとも、生まれたといっても、Rakudoは決して新しいプロジェクトではありません。それまでPerl 6 on Parrotと呼ばれていたものに新しい名前がついただけのことです。

Rakudoは、⁠駱駝道(Rakuda-do⁠⁠」の意味であり、⁠楽土」の意味でもあるというのが公式見解ですが、2006年のYAPC::Asiaでラリー・ウォール氏がキーノートのなかで「駱駝」⁠落第」⁠楽だ」と3つの単語を並べていたことを覚えている方もいるでしょう。

同年のYAPC::Asiaで混合語というタイトルで発表を行った火星ことマーティ・ポーリー(Marty Pauley)氏は、道が長くて、駱駝が遅いという記事の中で、Rakudoはむしろ「Rokudo(六道輪廻⁠⁠」の略だと見た方が(頭に「六」という数字もついているし)いいんじゃないかという意見を述べています。

2004年のYAPC::NAではじめてこの名前を持ち出したダミアン・コンウェイ氏は[2]⁠、⁠駱駝といえばPerlであり、Perl on Parrotこそ我々が取るべき道(Way⁠⁠」だからRakudoという名前を推したそうですが(もうひとつ「Rubyのふるさとである日本でPerl 6に興味を持ってくれる開発者が増えないかなあ」という期待もあったといいます[3]⁠、どちらかというとこれは「There's more than one Way to do it.(やり方はひとつではない⁠⁠」というPerlのモットーをこそ体現した名前だったのかもしれません。

Perl 6の開発チームは、この改名と前後して「Perl 6というのはあくまでも『仕様』であり、その仕様を満たす(公式仕様テストに通る)ものは、どのような形で書かれていようと、Perl 6の実装である」という方針を打ち出します[4]⁠。

これは、一見、実装の遅れているRakudoからオフィシャルの地位を剥奪して、Pugsなどの実装と横一線に並べただけのようにも見えますが、その真意はむしろ、仕様と実装に別々の名前を付けることで、何がどのような状態にあるのか、明確に区別することにあったようです。

たとえば、一口に「リソースを集中する」といっても、単にRakudoで実装されていないだけなのか、Parrot側の実装に問題があって実装が遅れているのか、それともPerl 6の仕様そのものに問題があってRakudoだけでなくPugsの方にまで影響が出ているのかで、リソースを投入すべき場所はかわってきます。

Perl 6という名前を仕様に限定することで、外から様子見をしている人にも話が見えやすくなりますし、すべてをひっくるめて「Perl 6はまだ……」と言われるのを避けられるようになります。

公式仕様テストの整理と増加

こうして芸名を変え、サイトや、のちにはリポジトリも独自のものを用意して、ほとんど一から仕切り直したRakudoの開発チームは、Rakudo本体の開発と平行して、⁠公式仕様テスト」の整備を始めます。

当時、Pugsのリポジトリには19000個ほどのテストが用意されていたのですが、そのなかには2005年当時とは仕様が変わっているものや、そもそも解釈が間違っていたもの、Synopsisとうまく対応が取れていないものも少なからずありました。

これらを精査して、あるものは修正し、あるものは配置をかえていった結果、2008年5月22日の段階では2905個しかなかった公式仕様テストは、2008年12月31日の段階で9863個になり、どんな修正が入ってもかならず合格させたい後退テストの数や、実際に(スキップしなくても)合格するようになったテストの数も、それぞれ564個から7612個、223個から5911個へと激増します[5]⁠。

このテストの拡充はいまもなお続いており、2009年8月12日時点では、17636個の公式仕様テストのうち、後退テストに分類されているものが15098個、そのうち12303個が合格という状態になっています。

参考までにPerl 5系列のテスト数を拾ってみると、Perl 5.005_04本体のテスト(いわゆるminitest)がおよそ4000、5.6.2が8000、5.8.1が27000、5.8.9が68000、5.10.1で80000ほど。コアモジュールなどのテストを含めると、5.005_04が6500、5.6.2が14000、5.8.1が78000、5.8.9が14万、5.10.1が23万ほどになります。

仕様に準拠しているかどうかと実用性は別物です

もちろんRakudoの実装がこの先もいまのようなハイペースで進む保証はありません。いまは2008年5月にイアン・ヘーグ(Ian Hague)氏が「ラストスパートのための軍資金に」と提供してくださった20万ドルもの助成金のおかげで1月1000件近いペースでテストと実装が増えていますが、先行していたPugsのテストは近いうちに使い切ってしまうでしょうし、設計側でもっと議論を深める必要があるポイントもどんどん出てきています(それに呼応して、仕様の方でも草稿段階のSynopsisが大量に追加されてきています⁠⁠。細部についてはいずれまたじっくり腰を落ち着けて取り組まなければならない時期も来るはずです。

それでも、ごく単純に考えれば、RakudoはすでにPerl 5.5系列や5.6系列よりはよくテストされていますし、来春にはおそらく初期のPerl 5.8系列にかなり近いところまでは到達していることでしょう。

たしかにロードマップ的にはもっと先があることはわかっていますし、クリティカルな場面で使うには時期尚早です。でも、先の発表を聞いて「なんだ、サブセットなのか」とがっかりした人は、もう一度仕様と実用性の関係を考え直してみる必要があるのではないでしょうか。

Pugsのバージョン番号は、6.0から始まります。最終目標は2πに設定されていました。小学生レベルのことしかしないからπ≒3でも用は足りる、という人にとっては2005年の段階でもう十分使えましたし、理想論でしか物事をはかれない人は、もちろん小数点何桁まで追いかけたところで、ゴールにたどり着くことはありません。

RakudoやParrot、⁠仕様としての)Perl 6の場合も同じでしょう。⁠公式仕様テストを100パーセント満たすものだけがPerl 6である」と杓子定規に考えるなら、ひとつ新しい仕様が増えて、すべてのテストが通らなくなった途端にその実装はPerl 6ではないことになってしまうでしょうが、それは――テスト駆動開発をしているPerl 6であればなおさらのこと――あまりに非現実的な見方というものです。

フィードバックを得るためのリリース

いったい何パーセント満たせばPerl 6の実装と認められるのか、みなさんのPerl 6に対する期待値がどのくらいで、現状の実装がそのどこまでを満たしているのかは、おそらく誰にもわかりません。

ただ、Perl 6にかかわるすべての人がいまもっとも必要としているのは、理想論や単なるスニペットではなく、実際のアプリケーションをつくってみたときに出てくる「あれが足りない、これはおかしい、これはどうすればいいんだろう」というフィードバックです。

いまでもすでにThe Perl Foundationの助成金を受けてPerl 6向けの軽量ウェブフレームワークの開発が進められていますが、Perl 6やRakudoをよりよいものにしていくためには、Perl 6を知り尽くした(ある意味突拍子もないコードは書けなくなっている)人以外からのフィードバックが不可欠です。

とはいえ、RakudoとParrotの開発版を落としてきてコンパイルして……という手順は、Perl 6でコーディングしたいだけの人にとってはいささか敷居が高いのも本当のこと。

それなら、バージョン1.0とは言えないけれど、毎月リリースされている開発版ほど手間をかけずに利用できるようなものを用意すればいいんじゃないか、ということで生まれたのが、バージョン「任意」を意味するRakudo *だったわけです。

待っているだけでは始まりません

Rakudo *にさらにバージョンがつくのか、それとも本当にスター、アスタリスクだけつけてリリースされるのかは、いまの段階でははっきりしません。機能的にも、どこがTodoとして残ってしまうかはまだわかりませんが、どの機能が動作するか(あるいはしないか)はRakudoサイトのステータスページや、月々のリリースノートに記載されています[6]⁠。

ただし、これはあくまでも「開発版は怖い/面倒」という人のためのものです。せっかちな人は、Rakudo *を待つまでもなく、githubにあるリポジトリからソースを持ってきてコンパイルなりインストールなりすれば、いますぐにでも開発を始められます。

2009年8月19日には、Rakudoになってから20番目の開発版となるコードネーム「PDX」が公開されました(2009年2月以降、Rakudoは(特に問題がなければ)Parrotの定期リリースの2日後に開発版をリリースすることになっています⁠⁠。この開発版には、これまでRakudoに貢献のあったPerl Mongersグループの名前が冠されることになっています。

あいにく日本のPerl Mongersグループの名前はまだ候補にあがっていませんが(現在の候補についてはリポジトリ内のdoc/release_guide.podに記載されています⁠⁠、せっかくの機会ですからみなさんも少しPerl 6でコードを書いてみませんか。

The Perl FoundationのWikiにもいくつか候補があがっていますが、大きなものから小さなものまで、つくるべきものはいろいろあります。

連載第1回では、Perlの父ラリー・ウォール氏の言葉として、⁠Perl 5までは親の責任で育て上げましたが、Perl 6を一人前の大人にするのはみなさんであってほしい」という一節を紹介しました。⁠Perl 6マダァ?」と待っているだけでは何も始まりません。

なお、Rakudo *については来月開催されるYAPC::AsiaでもBlatislava.pm[7]のジョナサン・ワーシントン(Jonathan Worthington)氏によるセッションが用意されています。氏は、2008年4月から(14番目の開発版にその名が残る)Vienna.pmの助成金を受けてRakudoの開発にあたっている古株の開発者です。もっと突っ込んだ経緯や最新情報を知りたい方は、ぜひ氏のセッションにご参加ください。

Rakudoは遅いという方には

なお、公平のため、Perl 6の実装としてはここで取り上げたPugsやRakudoのほかに、SMOP(Simple Meta Object Programming)というものもあります。いまはTPFやGoogle Summer of Codeの助成金を受けながら大規模なリファクタリングを行っているところのようですが、こちらはもっと現実的な路線を行くことを目標に、エンジン部分をCでごりごり書いているのがひとつの特徴のようです。Rakudo/Parrotもある程度実装が固まって最適化のフェーズに入れば実用的なスピードが得られるようになるでしょうが、待ちきれないという方はこちらに注目してみるのもよいかもしれません。

おすすめ記事

記事・ニュース一覧