セカンドシステム症候群にまつわる3つの話―Perl 6, Python 3, PHP 6

この10年間で、3つのメジャーなプログラミング言語が、それぞれPerl 6、Python 3、PHP 6へと大幅なバージョンアップに乗り出しました。ところが、Unicodeのサポート問題などの表面的な類似点があるにも関わらず、根本的に異なった展開を見せています。

今年Perl 6.0.0が公式にリリースされるのに伴い、いま一度振り返って、リリース後の展開について考えてみるのに、今はちょうどいいタイミングでしょう。

PHP 6

これを書いていることが自分でも信じられないのですが、PHPから学ぶべきことがあるかどうか見ていきましょう。Zend TechnologiesのCEOであるAndi Gutmans氏は2008年2月のインタビューでこう答えています。

我々はPHP 6に対し長いサイクルでのロールアウトを予想している。Perlプロジェクトに対しては、プロジェクトのコントリビューターがいまだPerl 6に着手中なことを考えると、あと6年はかかるだろう。Perlと同じ道をたどらせたくない。世間はMicrosoftを揶揄するが、Perl 6を見てほしい。

これに対し、PerlBuzzのAndy Lester氏は以下のように答えています

確かにPHP 6はPerl 6よりも短いサイクルでのリリースになるかもしれない。だが、結局は、我々はPerl 6をリリースし、そちらはPHPの現バージョンのままだということに変わりない。
個人的な見解として
愛をこめて
Andyより

この予想がどう転がったでしょうか? そうです、6年以上にわたる開発の末、私たちは結局PHP 6を見ることはかないませんでした。Perl 6やPHP 6の開発にどれだけ時間がかかったかを見ていると、6という数字は失敗の象徴のような気がしてきました。そこでPHP 6をやめて、名前をPHP 7に変えれば全て解決! これは実際に6から7のRFC上で行われた推測の一例です(ブラウザに被害が降りかかる前に誰かES6仲間へ伝えた方がいいですよ)。

しかし、ここでバージョン番号を変える最大の意図は、PHPの次のメジャーバージョンアップに含まれる新機能が削減されたことの正当化です。PHP 7は以下を加える予定です

  • Zendエンジンに対する“大幅なパフォーマンスの改良”(HHVMはすでに高速である)
  • Zendエンジンに対するJIT(すでにHHVMで使用可能)
  • 抽象構文木(AST)生成
  • 非同期IOと関数
  • スタンドアロン型マルチ・スレッドWebサーバ(HHVM)
    • 自分のサーバにプログラミング言語それ自体を提供するのなら、イケているでしょう。

編集: このブログやHacker Newsを閲覧している人は、上記の機能リストは適切でないところから引用され、PHP 6の大半は5.3に取り込まれたと指摘してきました。ジェネレータの改良や、??のような新しい演算子を含め、PHP 7の機能についてよくまとめられているこちらの記事を見てください。しかしながら、同じような分析のほとんどに当てはまるのが、「最終的な結果は極めて少ない後方互換性のない変換であり、約束されていたUnicodeの改良を含む改訂ではない」ということです。

Perl 6

一方で6.0.0のリリースに15年かかったPerl 6は今年のクリスマスにリリースが予定されています。リリース時期については心許ない引用元が幾らかありますが、とても古いものにはなりますが「2027年にPerl 6のリリース準備ができている」というこのブログの予想をリンクしたいと思います。

現状では、Perl 6は以下の新しい機能が予定されています。

  • あらゆる箇所での型システム(PHPのようなタイプヒンティングに留まらない)
    • ほとんどの短いスクリプトコードで、型を無視し続ける機能
    • エラーを検知するために静的な型チェックを使用する機能
    • ネイティブ型(Cの文字列、符号なしint型など)による新しい潜在性能の解放
    • メタオブジェクトのプログラミングが使用可能
  • saneネイティブ関数呼び出しインタフェース

  • より多くのバックエンド(JavaScript)と共に、複数の仮想マシン上で(JVMやMoarVM)実行できるRakudo Perl 6

    • Perl 6をバイトコードやASTにコンパイルできる
    • 仮想マシンのJITを利用する
  • 完全な構文リファクタリング
    • Inline::Perl5の利用で、旧バージョンに対して完全な互換性を持つ
    • 一貫性のある構文
  • デフォルトでNFG(書記素)を使ったUnicodeのネイティブサポート
  • 健全なマクロ
    • 上記で示したとおり、ASTのこと
  • 正規表現が構文へと進化。つまり第一級言語
    • PCREは(Perl 5のモジュールを除いて)Perlとの互換性はなくなってしまったものの、より読みやすくなっている
  • 並行処理を簡単に使える
    • 演算子の中にはオートスレッドするものがある
    • 演算のためのジャンクション型
  • モジュールのAPIが完全に変更されたとしても、コードが壊れないことを保証するため、モジュールのバージョン管理を実施。もちろん、これはバージョンを宣言した時に限られる

正直に言いますと、上記に挙げた機能はほんの一部でしかありません。サブルーチンシグネチャやスマートマッチングといった、Perl 5のコア機能としてすでに作られているものもここからは除かれています。そしてこれらは全て、現在動いている機能です。

気味が悪いことに、Andyが軽々しく予言した内容は全て現実となりました。最終的にPerl 6はリリースされ、PHPは、いまだに古いバージョンのまま存在しています。繰り返し言いますが、Perl 6はリリースされたのです。問題なく動作していますし、今年にはメジャーバージョンアップを控えています。そのバージョンには、もともと約束されていたものよりも、多くの機能が存在しています。

しかし今もなお、Perl 6に疑念を抱く人たちが存在します。実際、Perl 6はPerl 6と名乗っても構わないけれども、Perl 5の次のバージョンはPerl 7であるべきだと、まじめに言う人々もいるのです。そのとおりです。この考え方は、一般的なPerlコミュニティでは受け入れられませんでしたが、PHPはその1年後に実際にバージョンを1つスキップしました。私自身は、これはPHPがPerlの最悪な考え方を真似したという、もう1つの例だと考えています。

Python 3

一方で、Pythonのグループは、健全なPython 3を維持してきました。そしてアップデートし続けるため、互換性のない変更は最小限にとどめたのです。Python 3は2009年の初め、つまり6年前にリリースされた言語です。

Python 3の新たな機能を以下に挙げましょう。

  • 良識のあるUnicode処理
    • 互換性のない変更を許容したために、互換性に影響する変更があった
  • スタイルの一貫性を保つための様々な名称変更
  • 可能なかぎり自動的にCモジュールをロード
  • 例外のリファクタ
  • 古いOSのサポートを中止
  • 一般的に質の悪いAPIと併せて古い関数は削除
  • print()関数を採用しprintは削除。この対処が実施された理由としては、建前上はAPIの連続性を保つためで、本音は人々をもてあそぶためと思われる

では、この機能を入れた結果は、どうなったのでしょうか? 私のMacBookは完全にアップデートされているのですが、そのMacBookにプリインストールされているPythonのバージョンは、2.7.6です。一方、Ubuntuにインスト-ルされているバージョンは少なくとも3.4.0です。確かに、OSSアップデートの点において、Appleの対応はひどいと言われています。Python 3に関しては、XCodeにプリインストールするため、Appleの中にいる誰かが6年間十分にPythonのことを気に懸けたのだろうと、あなたは思っているもしれませんが、結局、Pythonは命取りになるGPLv3ライセンスを持っていないのです。

有効性とは、開発者に選ばれることの裏返しでもあります。Python 3はその点で、よい話がありません。昨年今年4月の統計を見てみると、開発者によるPython 3の選択率は非常に低くなっています。あろうことか、Pythonコミュニティ内の23パーセントもの人々さえもが、いまだにPython 3は失敗だったと考えているのです。言語としては明らかに改善されているにもかかわらず、失敗作という評判を覆すのは難しいでしょう。

セカンドデプロイメント症候群

つまり、今まで書いてきたことをまとめると、セカンドシステム症候群は重要な問題だと言えるでしょう。しかし問題はそれだけではありません。プログラミング言語の大幅な修正を達成するのは難しいことですが、そのような互換性のない変更を加えるのと同じように、その新しいバージョンが世間に幅広く受け入れられることも困難です。セカンドデプロイメント症候群は、新たなシステムを最初に作るのと同じくらい、既存の言語に大幅な修正を加えることは困難を伴うものであるということを示しています。

その結果、セカンドシステムを根本的に異なる方法で構築する3つのソフトウェアコミュニティがあるのです。PHPはひどいデザインがぎゅうぎゅう詰めになっている状態なので、使いやすくなることを願うばかりです。しかしPHPのコミュニティは実質的にPHP 6を諦めることを決め、PHP 6の第一の問題であるUnicodeサポートと関係ない、追加の変更だけを提供しています。Pythonは、達成可能な変更をいくつか加えることを決め、それを3年以内に実行に移し、出荷しました。本当に役に立つ改良があったにもかかわらず、ごくわずかの人しか使っていません。

Perlは“一気に全てを壊す”というビジョンにこだわることを決め、バージョンアップに15年の年月を費やしています。これはHTML 5の開発期間に匹敵する長さです。この間にデザインは進化し続け、失敗しがちだったコードのマルチスレッド化を簡単にするといったような、より現代的なニーズを組み込んできました。“決定的な仕様がない”ことに関する不満は多くありますが、仕様は最後まで完成させるべきではないということを、苦い経験から学んでいます。

15年もの年月を開発に費やすなんてバカげている、と言うのは簡単ですが、他のスクリプト言語のセカンドシステムを見ると、Perl 6はこのような大がかりな転換を10年以内に成し遂げようと考えていなかったのは明らかです。この転換がPerlにうまく働くかということは、まだはっきりしていません。

Perl 5のバックグラウンドからPerl 6を試した人はほぼ誰でも、Perl 6の転換をとても気に入りますが、大抵はその後、“ここまで遅い必要はないんじゃないか?”と思いはじめます。Perl 6の最適化は未熟ではありませんが、いまだに未完成です。一般的に言えば、評価はプラスではありません。そして他の言語で導入されたような互換性のない変化とは異なり、Inline::Perl 5は同じプログラム内で複数のバージョンのPerlが共存することを許します。

これで十分でしょうか? 結論を出すのは早すぎます。Perl 5 は、何世代も前のプログラマが書いたシェルスクリプトからのテキスト出力に変更を加えながら、永遠にとは言わないにしても、最低でもあと5年は続きます。Perl 6は遍在性や年代もののコード、言語の親しみやすさをめぐって苦しい戦いをすることになるでしょう。

どのくらい受け入れられるかは、Perl 6が次に直面する大きな試練です。今から6年後、減少し続けるPerlユーザの間で、Perl 5がまだ絶大な支持を集めている可能性は大いにあります。結局、Pythonも同じ状況 にあるのかもしれません。Perlは、すでに下向きになっている傾向を覆す必要があります。これはそもそも、少なくとも部分的には、Perl 6のあり得ないほど長い開発期間がもたらしたものです。

Perl 6の成功を確実にするためにできる最良のアドバイスは、開発者がPerl 6でコードを書き始めることです。それも、今すぐに。Perl 6は十分に安定しています。リリースから1年以内の利用可能な全てのモジュールは、人々に新しいバージョンについて議論を巻き起こすことになるでしょう。状況を冷静に見つめ、効率的に仕事をこなせば、多くの議論に勝つことができます。

その後は、つらい仕事になるでしょう。コードを配布するにあたり、十分な場所をデプロイしましたか? より多くの場所をデプロイするにあたり十分なコードは書かれていますか? aptやHomebrewのようなパッケージ管理システムはユーザベースのブートストラップを助けています。Perl 6が勝利するためには、そのようなキラーアプリを手に入れなくてはなりません。

今のところは、これは大きな賭けです。ポーカーの用語で例えれば、Python 3はコール、PHP 6はフォールド、Perl 6はオールインでしょう。圧倒的な改良のためには、わずらわしいアップグレードを行う価値があると人々が考えるなら、Perl 6の嘘みたいに長い開発プロセスが、皆に受け入れられるセカンドシステムを作るのに適しているでしょう。

この結果は、6年以内にお伝えしましょう。