実装が無かった 4 年半と、Pugs の 1 年 — Haskell で書かれた Perl 6

2005 年 2 月 1 日、Audrey Tang が Perl 6 の実装を Haskell で書き始めた。Pugs である。発表から 4 年半、設計文書は積み上がっていたが動くものが無かった。Pugs は数ヶ月で相当部分を動かし、そして実装そのものより大きなものを残した — 「実装するたびに公式のテストスイートにテストを書く」という運用。それが後に roast になり、Perl 6 の仕様観を作り替えた。

perlrakupugshaskellhistorytestingprogramming-languages

4 年半、動くものが無かった

前回、Perl 6 が変えようとした 9 項目を並べた。 どれも言語 1 つ分の仕事で、しかも互いに独立ではない、という話だった。

では、その間に何が起きていたか。

2000 年 7 月の発表から 2005 年初頭まで、Perl 6 には実用的に動く実装が無かった。 あったのは設計文書である。Apocalypse が書かれ、Synopsis が整理され、 Parrot(次回の主役)が開発されていた。しかし、Perl 6 のプログラムを書いて 動かせる環境は、実質的に存在しなかった。

4 年半である。

この期間が何を意味していたかを、まず書いておきたい。

設計文書だけで進む期間には、固有の危うさがある。

  • 書けば書くほど、決まったことが増えているように見える
  • しかし、実際に書いてみるまで分からないことが残り続ける
  • そして誰も書いていないので、それがまだ残っていることに気づけない

文書は積み上がる。進捗があるように見える。 検証されていない決定が、検証されないまま積み上がる。

2005 年 2 月 1 日

Audrey Tang が Perl 6 の実装を書き始めた。 言語は Haskell。プロジェクト名は Pugs(Perl 6 User’s Golfing System)。

なぜ Haskell だったのか

理由はいくつかある。

1. パーサコンビネータが使える。 Parsec を使えば、複雑な文法を素早く実装できる。 Perl 6 の文法は大きい。ここで速度が出ることは決定的だった。

2. 遅延評価が Perl 6 と対応する。 第 4 話で書いた遅延リスト・無限列は、 Haskell では言語の既定の挙動である。実装が素直になる。

3. 代数的データ型で AST が書きやすい。

そして、おそらくこれが一番大きい。

4. Audrey Tang が速く書ける言語だった。

ここに重要な判断がある。「Perl 6 を Perl で実装しなければならない」という前提を外したことだ。

当時の空気として、Perl 6 の実装は Parrot の上に作るものだ、という了解があった。 Pugs はそれを無視した。動くものを最速で作ることを、他の全部より優先した。

何が起きたか — 速度

Pugs の進捗は、当時の人々の証言によれば異常に速かった。 開始から数ヶ月で Perl 6 の相当部分が動き、 世界で初めて Perl 6 のプログラムが実用的に書ける環境になった。

4 年半、動くものが無かった。そして 1 年で、動くようになった。

この対比が、Pugs の歴史的な意味のほぼ全部である。

Pugs が残した 3 つのもの

Pugs 自体は、現在使われていない。リポジトリはアーカイブされている。 それでも Pugs が Perl 6 史の転換点だとされるのは、制度として残ったものがあるからだ。

1. 仕様テスト — roast の起源

Audrey Tang は、Pugs で機能を実装するたびに 公式のテストスイートにテストを書くという運用を始めた。

これがなぜ重要か。

実装は複数あってよい。Pugs があり、Parrot 上の実装があり、後に他のものも現れる。 しかしテストは共有する。 テストは「Pugs がこう動く」ではなく、 「Perl 6 とはこう動くものである」を書いたものだからだ。

この運用が育って roastRepository Of All Spec Tests)になり、 最終的に「roast が仕様である」という形に至る。その話は次々回(第 7 話)でやる。

2. 実装が設計にフィードバックした

Pugs で実際に書いてみると、Synopsis の記述で決まらない点や、 書きにくい部分が具体的に出てくる。それが Synopsis へ戻された。

ここに、この連載で 5 つ目の「型」がある。

実装は、読んで分かる誤りとは別の種類の誤りを出す。

5 年分の設計文書があっても、書いてみるまで分からないことが残っていた。 そしてそれは、文書をもう一度読んでも見つからない類のものだった。

3. コミュニティの越境

Haskell コミュニティの人々が Perl 6 に関わるようになった。

Pugs は「Perl の人が Haskell を学ぶ」「Haskell の人が Perl 6 を知る」入口になり、 Perl 6 の設計に型システム側の語彙を持ち込んだ。

Audrey Tang はこの時期、コミットビットを非常に気前よく配ったことでも知られる。 パッチを送った人にすぐ commit 権を渡す運用で、参加のハードルを大きく下げた。

これは「動くものがある」ことの副次効果でもある。 動くものがあると、人は小さな貢献ができる。 設計文書には、小さな貢献の仕方が無い。

減速と、役割の終わり

2007 年前後から Pugs の開発は減速する。 Audrey Tang が健康上の理由などで第一線から退いたことが直接的な要因だった。

⚠️ ここは公表されている範囲を超えて書くべきではない。 事実として書けるのは、専任に近い担い手が 1 人抜けたことが、 プロジェクトの速度に直接響いたということだ。

第 3 話で「15 年かかった理由」の 4 つ目に「専任の担い手が薄かった」と書いた。 Pugs はその最も鮮明な例である。1 人の離脱が、プロジェクト全体の速度を変えた。

(Audrey Tang はその後、台湾のデジタル担当政務委員・デジタル発展部長を務めた。)

位置づけ

Pugs は「失敗した実装」ではない。仕様と実装の関係を作り替えた実装である。

Pugs 以前 Pugs 以後
設計文書(Synopsis)が正 テストスイート(roast)が正へ向かう
実装は仕様に従うもの 実装が仕様を動かすこともある
Perl 6 は Parrot の上のもの 実装は複数あってよい

そして、もう 1 つ。

Pugs は「動くものがあること」の価値を証明した。 4 年半の設計と、1 年の実装。後者が空気を変えた。 これは設計が無駄だったという意味ではない — Pugs は Synopsis があったから速く書けた。 両方要る、しかし片方だけでは進まない、という話だ。

次回は、その「もう片方」が大きく外れた話をする。 Perl 6 は、実装基盤の選定で一度賭けを外している。


次回(第 6 話): 汎用 VM という賭け。 Parrot は「動的言語共通の VM」を目指し、そして誰のものにもならなかった。 MoarVM は何を捨てることで完成したのか。

← Back to Perl と Raku の系譜