IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  Linux  >

魅惑的なPython: Python実装に駆り立てたもの

VyperおよびStackless Pythonの作者とのインタビュー

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 初級

David Mertz (mertz@gnosis.cx), President, Gnosis Software, Inc.

2000年 10月 01日

"Python" について語るときにほとんどのプログラマーが思い浮かべるのは、"CPython" と呼ばれることのある (Cで実装されているためです) 特定の実装のことです。しかし、言語仕様としてのPythonは、Guido van Rossumによる参考実装の進化に伴って、これまでに何回か実装されてきました。この記事は、2つの非標準PythonsであるStacklessおよびVyperの作者とのインタビューに注釈を加えたものです。

私が数えたところ、現在ダウンロードして実行することのできるPythonの実装は4つあり、さらに現在もう1つが作成中です。それぞれの実装には、誕生するにいたった興味深い理由があります。この点に関して、この記事の中で、実装した本人の口から語られています。

コンパイラーまたはインタープリターを別のプラットフォーム向けにコンパイルすると、(各コンパイラーに設定されるコンパイル・オプションの差によって)ごくわずかな違いしかない実装が生成されるますが、(私が)興味を引かれる実装は、このようなプラットフォーム間の差異を超えた新たな実装です。現に、この記事で取り上げるPython実装は、それ自体が多くの意味でマルチプラットフォームになっています。また、実装というアイデアはバージョン のアイデアとは異なります。ここで扱うすべての実装は、言語仕様の観点から見ると、基本的に同じ言語バージョン (1.5.2) に基づいています。CPython 1.6/2.0/3000は明らかに、すでに部分的には新しい仕様を基礎にしていますが、その他の実装は、前述の言語レベルに基づいた機能を備えています。

どのプログラミング言語が、どの程度の頻度で、どのような理由により、また誰によって再実装されているのでしょうか。言語に関するこのような点について特徴を述べるのは困難です。マーケットにおいてPythonとほぼ同じニッチに位 置付けられるいくつかの人気のある言語 -- Perl、REBOL、PHPなど --には、(多数のプラットフォーム向けにコンパイルされていますが) 1つの実装だけしかありません。TCLはPerl/PHPに最もよく似ていますが、JaclというJavaプラットフォーム向けのバージョンが存在します。それと対極にあるC、Awk、COBOL、REXX、およびJavaなどの言語は、いずれも、数え切れないほど何回も実装されています。しかしそれらの再実装は、実装に関するコンセプトおよび理論的な事情から行われるというよりも、ライセンスやマーケティングの事情から行われている傾向があります。特にアカデミックな興味を引くような言語 (特に、SmalltalkやEiffelのような機能的、論理的、あるいは超純粋OOP言語) は、何度も再実装されるように思えます。Lispには、何百とまでは言えないとしても、数十の実装と末裔が存在します。

これから検討するPythonの実装とは異なり、Lispの末裔たちには、新しい実装に伴って多くの新奇な言語 仕様が導入されています。多くの場合Pythonの実装では、主要なCPythonバージョンと同じ Python言語が実装されています。そして現行のすべてのバージョンはオープン・ソースの共同作業の成果 です。こうした共同作業では、技術革新がマーケットでの地位を狙ったものであるということは一切無く、また しばしばオープン・ソース・プロジェクトを分裂させるもとになるライセンス競争を意識したものでもありません。さらに、別のPythonバージョンと言っても、それは実のところ、従来の意味における枝分かれ ではなく、むしろ、「Pythonの実装」という表現形式をとった、いままでとは異なるコンセプトに焦点が合わされているのです。

JPythonとPython.NETの2つの実装については詳しく論じませんので、ここで簡単に述べておきます。JPythonはJavaで書かれたコンパイラーであり、Pythonソース・コードをJavaバイト・コードにコンパイルするものです。Pythonアプリケーションは、最終的にはJVM内で実行されます (ユーザーはおそらく、それがJavaでなくPythonソース・コードで書かれたことに気付かず、またそのようなことを気にする必要もありません)。Python.NETはこれから出荷される実装ですが、(少なくとも構造の点では) JPythonに似たものになるでしょう。Python.NETにより、PythonはMicrosoftの .NETプロジェクトに組み込まれることになります。このプロジェクトは基本的には、さまざまな言語 (新しいC#、Visual Basic、C++、およびPython) で書かれたプログラムを実行することのできる、非Java VMであると言えます。これらの実装の開発者が今後言うことに耳を傾けてください。

以下で、理論的に魅力のある2つの実装の開発者から話を聞くことにします。John Max SkallerからVyper について、またChristian TismerからStackless Python について聞きます。

Vyper: 作者John Max Skallerとのインタビュー

Vyperは、機能型言語Ocaml (3.00) で書かれたPython言語の実装です。他のPython実装とは対照的に、Vyperは多くの (オプションの) 言語拡張機能、すなわち、より強力なスコープ化規則および新規機能を備えています。Vyperは、現在は活発な開発が行われなくなっていますが、今後機能強化される可能性があります (ソース・コードを含むVyperの入手については、参考文献を参照してください)。私はVyperの作者John Max Skallerに、Vyperを作成した動機を尋ねました。

Skaller: Vyperを作成した理由は2つあります。まず1つは、Python、特にその単純さが気に入っていたからです。しかし、スコープ化がないこと、また標準機能の域を超えるとその道の専門家の手を借りなければならないという点が、気に入りませんでした。そこで、Pythonとの互換性を維持しながら、機能型プログラミング言語のいくつかの概念が組み込まれた、より高度なプログラミング言語を作成して、それらの問題を解決しようと考えました。
2番目の理由はパフォーマンスです。私の手元には、interscriptという主要なPythonプログラムがあります。これはリテレート・プログラミング (LP) ツールなのですが、Pythonに良い構造が存在しないという問題 (上記を参照) だけでなく、パフォーマンス上の問題も抱えていました。
Mertz: リテレート・プログラミングがVyperの作成の動機となっているということですが、読者のために、リテレート・プログラミングとはどういうものなのか、少し説明してください。
Skaller: プログラムのドキュメントを (後追いで) 書かずに、プログラムを組み込んだ ドキュメントを書こう、という考え方です。Donald Knuthによって考案されたものです。
interscriptは プログラミング言語から独立した型設定プログラムであり、Pythonで書かれた任意の実行可能コードによってドキュメント内で 展開することができます。つまり、コードとドキュメントを任意に生成 することが可能になるのです。しかも、日常的な要求を満たすために、多数の事前作成された構造を使用することができます。
しかしLPは、高速にならなければ、主流テクノロジーとして受け入れられることはないでしょう。私は、高速化のために多くの努力を傾けましたが、結局のところ、Pythonの速度は、必要なことを行うのに十分なものではありませんでした。インタープリター言語でストリングを1文字ずつ処理するようでは、高速になるはずがありません。
そこで、Pythonコンパイラー を作成しようと考えました。こうすれば、少なくとも、この種のコードを最適化できるマシン語のバイナリーが生成できます。これが、Vyperのいくつかの拡張機能が作成された理由の1つです。つまり、最適化を可能にしたいということです。
私はコンパイラーを書いたわけではありません。コンパイル時にプログラムのすべてのモジュールをロードして、それによって得られたディクショナリーを実行可能バイナリーにfreeze するような、インタープリターを書くことを考えたのです。現在のVyperはインタープリターです。この言語を拡張することを楽しんでいたのですが、やがてコンパイラーを書く仕事をするようになり、作業を続ける時間がなくなってしまいました。
Mertz: Vyperの機能のうちで特に目新しいものは、Ocamlでの実装です。多くの読者はおそらく、コンパイラーやインタープリターというものは (マシン寄りにするために) Cで実装されるものであるとか、マシンが決まっている場合には、Python自体でコンパイラーを書くことができるとか思っているのではないでしょうか。なぜOcamlを使用するのですか?
Skaller: Ocamlはマシン・コードを直接生成します。Cに比べてもかなりパフォーマンスがよく、作業の種類によってはCよりも高速です。また、ガーベッジ・コレクターも備わっています。Ocamlは高水準言語ですが、C、C++、Python、その他の多くのいわゆる「高水準」言語とは異なります。
OcamlはPythonと同じように、機能型言語と命令型言語が混合した言語です。Vyperは、Python以上にPythonの機能的側面を強調しています。目立った設計上の不備、特に語彙スコープ化の欠如が改められています。
実際には、機能型プログラミングの背後には確固とした理論があるのに対し、命令型プログラミングには理論の裏付けがありません。つまり、機能型プログラミング言語は一般 に、開発の視点から見ると、どの命令型言語よりもはるかに優れているのに、基礎になっているハードウェアの命令型アーキテクチャーにふさわしい、システム・パフォーマンスが欠けていることが多いのです。

面白いことに、次の実装は、別の方向から考え出されたものですが、いくつかの点でVyperよりも優れています。

Skaller: このプロジェクトのもう1つの呼び物はStackless Pythonでした。これは、私が現在開発中のコンパイラーが行うのと同じことを行います。コオペこれは、Vyperではおそらく無理なことです。つまり、「超軽量スレッド」の実装 (イベント・ディスパッチャーにより起動されるコーオペラティブ・マルチタスキング) を可能にすることです。Vyperは、マシン・スタックを使用するOcamlに実装されます。マシン・スタックの使用は避けなければなりません。スタック切り替えは (サーバーから多数のクライアントを同時に処理するために) 非常に高コストになるからです。



上に戻る


Stackless Python: 作者Christian Tismerとのインタビュー

Stackless Pythonは、一見したところ 若干の手直しを加えたCPythonからの枝分かれのように見えるかもしれません。コーディングの点では、Stacklessは実際のPython Cコードをほんの少し手直し (さらに、"truth" を再定義) しただけです。しかし、Christian Tismer (Stackless Pythonの作者) がStacklessで導入した概念は、意味深いものです。これは、「継続(continuation)」という概念(およびそれをPythonでプログラムする方法)です。

これを簡単な言葉で説明すると、継続とは、プログラムがその後行うことのできるすべてのものを、プログラムの特定個所で表現したものです。継続は、初期条件に依存する潜在的なものです。伝統的な方法におけるループとは異なり、異なる初期条件を指定して同じ継続を繰り返し呼び出すことができます。私が目にしたある大まかな主張によると、継続は、理論的な面では、他のすべての制御構造よりも基本的なもので、それらの基礎になるものです。こういう考えを聞かされて頭が混乱したとしても、心配はいりません。もっともな反応です。

最初に、参考文献に示されたTismerの背景記事を読むと、理解がしやすくなります。彼が参照しているものを読むと、さらに理解を広げることができます。しかし、ここでは、もう少し一般的なレベルでTismerと話をすることにします。

Mertz: Stackless Pythonとは、いったいどういうものなのですか? 初心者に分かりやすくStacklessの特徴を説明したものはありますか?
Tismer: Stackless PythonはCスタックに状態を保管しないPython実装です。スタックは (ユーザーが必要とするだけ) 用意されているのですが、Pythonスタックなのです。
Cスタックは、あらかじめ規定された手順に従わないと、Cのような言語から整合性を保って変更することはできません。ユーザーは大きな責任を負うことになります。離れたときとまったく逆の方法で、まったく同じ個所に戻る必要があります。
「通常の」プログラマーには、最初は、これが制約事項になるとは考えられません。最初から、スタックに注意を注ぐことを学ぶ必要があります。スタックそのものには不都合な点がなく、通 常は、そこで指示された実行順序に従うべきです。しかし、それだからといって、こうしたスタック・シーケンスの1つが完了するまで待たなければ、別のスタック・シーケンスを実行できないということはありません。
プログラマーは、非ブロッキングの呼び出しやコールバックを行う必要が生じたときに、このことに気がつくのです。突然スタックが立ちはだかり、スレッドを使用したり、状態をオブジェクトに明示的に保管したり、明示的で切り替え可能なスタックを作成したり、ということが必要になります。Stacklessの目的は、こうした問題からプログラマーを救い出すことです。
Mertz: Stacklessの目標は、CPythonと100%バイナリー互換にすることなのですか?
Tismer: Stacklessは、現在でも100%バイナリー互換です。つまり、Python 1.5.2をインストールし、Python15.dllを私のファイルで置き換えても、すべての拡張モジュールを含め、あらゆるものがきちんと機能します。すべての拡張機能に配慮することは避けたかったので、これは目標ではなく、必要だったのです。
Mertz: Stackless Pythonについて書かれたものを読むことは、私にとって、非常に魅力的なことでした。俗世間のほとんどのプログラマーと同じように、私は、それに専念するわけにはいきませんでした。しかしそのことで、逆に、読むのがとても楽しくなりました。
Tismer: ええ、私も俗世間派です。継続とは何かという明確なアイディアを持たず、またPython内でどのような使い勝手にすべきかも定かでないまま、この手のものを実装するのが、どれほど難しかったかは、想像していただけると思います。考えもしなかったことを実行するのは、大きな挑戦でした。やり終えてみると、考えをまとめたり再設計したりすることは、そう難しいことではありませんでした。しかしそれに没頭していた6か月のうち5か月は、画面をにらんだりキーボードに頭をたたき付けたり していたのではないでしょうか。
継続は売り物になりにくいものです。コルーチン、ジェネレーター、それに、特にマイクロスレッドは、それよりも簡単です。上記のすべては、明示的な継続を使用しなくても実装することができます。しかし、すでに継続を使用したことのあるユーザーには、こうした他の構造へのステップが非常に小さなものであって、継続を採用すべきであることが分かります。ですから、マーケティング戦略を変更し、これ以上は継続自体を売り込もうとしないで、継続の成果 を売ることにしました。これからも継続は、見る目のある人々には利用してもらえるはずです。
Mertz: アメリカ人のエンジニアとフランス人のエンジニアについてのジョークがあります。アメリカ人のチームがフランス人のチームにプロトタイプを持ち込みます。フランス人チームの反応は、こうです。「実際にきちんと機能するけれど、理論的にはどうなっているの?」 このジョークは「フランス式」スタイルをからかっているものなのでしょうが、私の気持ちとしては、完全に「フランス式 」の反応に同感です。このジョークの特定の国民に対するステレオタイプ的な決め付け方を括弧 に入れて考えると、私をStacklessに引き込むものは、この「フランス式 」に同感する心理なのです。CPythonは実際にきちんと機能するのですが、Stacklessには理屈のうえで納得させるものがあるのです。(言い換えると、たとえば、継続の抽象的な純粋性のほうが、マイクロスレッドによる高速なコンテキスト切り替えよりも、私個人の興味をそそるのです。)
Tismer: 私の気持ちも、それに少し似ています。Cスタックを組み込まなくてもCPythonを実装できることが分かってから、私は、この方法で実装しなければならないと確信しました。それ以外の方法はすべて、私にしてみると正気の沙汰ではありません。CPythonはすでにフレーム・オブジェクトというオーバーヘッドを被っていますが、Cスタックと結び付くことによってすべての自由を放棄することになります。わたしは、Pythonを自由の身にしなければならないと感じたのです。:-)
このプロジェクトは1999年の5月に開始しました。Sam Rushingがハードウェア・コルーチンの実装に取り組んでいましたので、Python開発の議論を始めました。このようにスタックをコピーするという小手先の技では、Pythonがものになるはずがないことは明らかでした。しかし、移植可能で整合性のとれたコルーチン実装を行えば、なんとかなりそうに思えました。残念ながら、これは不可能でした。Steve Majewskiが5年前にあきらめていました。Pythonを完全に書き直さないかぎり、この問題を解決できないことに気付いたのです。
これは、むずかしい課題でした。はっきりさせる必要がありました。可能なのであれば、それを実装し、不可能なのであれば、不可能であることを証明したかったのです。その後まもなく、最初にいろいろ考えて試した後で、Samが私にcall/ccのこと、その効果 がすばらしいことを話してくれたのです。このときには、私はなぜそれがコルーチンよりも効果 的であるのか、分からなかったのですが、彼を信じて実装してみました。6回か7回、ほとんど完全な書き直しを繰り返すうちに、よく分かってきました。
最終的には、猛スピードでスレッドを作成したかったのですが、私の一番の目的は、自分の作業をどこまで進展させることができるのかを知ることでした。
Mertz: 実用的な面では、Stacklessによってどのようなパフォーマンス向上が得られそうですか? 現在の実装では、どの程度向上しているのでしょうか? 今後の工夫で、さらにどれほどのパフォーマンスの向上が期待できますか? Stacklessの恩恵を最もよく受けそうなのは、どのような種類のアプリケーションですか?
Tismer: 現行の実装では、従来の呼び出しスキームに比べて、Stacklessが特に優れているとは言えません。通常のPythonは、新規のインタープリターへの再帰を開始します。Stacklessはディスパッチャーまでアンワインドし、そこからインタープリターを開始します。これは、大体同じです。本当のパフォーマンス向上は、コルーチンとスレッドの実装によって得られます。これらは、標準Pythonではクラスごとにシミュレートするか、実際のスレッドにする必要がありますが、Stacklessでは、それよりもはるかに直接的な方法で実装することができるからです。
コア部分のそれ以上の改良は、命令コード・セットを劇的に変更しなければ、可能にならないと思います。しかし、継続その他の組み込みサポートを増やして実装し直すと、そうした速度をかなり向上させることができます。
大きな恩恵を受けそうな特定のアプリケーションとしては、Swarmシミュレーションや、きわめて大勢のプレーヤーが小さなタスクを実行するマルチユーザー・ゲームが考えられます。たとえば、EVEゲーム (下記の参考文献を参照) がそうです。このゲームは、Stackless Pythonを使用して開発が行われているところです。
Mertz: StacklessをCPythonの主要部分に組み込むことについては、どう考えていますか? Stacklessは、使用可能な枝分かれと同等な性能をもっているのでしょうか? あるいは、コア・バージョンになったときにはそれよりも良くなるのでしょうか?
Tismer: それについては、賛否両論の意見があります。まず否定の理由を先に言いますと、それは私がStackless実装を手掛けているかぎり、Stacklessは私のものであり、どうしてだの、なぜだのと論じる必要がないからです。しかし同時に、私はなんとかしてCVSに対応していきたいとがんばっています (しかし、うまくいっていません)。これは、ほかの人に任せたほうがいいでしょう。
その他のPythonユーザーで、必ずしも風変わりなことには興味がない人々は、Stacklessをまったく認めないでしょう。たまたま速度が速いということや、現在の最大再帰レベルがオプションであってハードウェア限界で決まっているのではないということだけしか、評価されないでしょう。これとは別に、すべてのユーザーに対して約束できることがあります。実行状態が保存可能になるということです。つまり、実行中のプログラムを保管して、友達に送り、実行を続けることができるのです。
結論としては、私は賛成です。ただし、私が作成したもの全てをコア・バージョンに投入できるという条件付きですが。同時に、すでに何回か提案されたような中途半端な解決策は望んでいません。
Mertz: Stacklessが今後進む方向については、どのように考えていますか? 今進行中のもので、新しいことやこれまでと違うことはありますか? Stacklessは、今でも再帰に縛られなければならないのですか? 再帰はなくなるのでしょうか?
Tismer: 保存サポートが部分的に実装されます。これは、最初はマイクロスレッドで使用されるようになります。現時点ではマイクロスレッドが最も明確に抽象化されているからです。マイクロスレッドは、他の再帰の問題が存在しない「クリーン・ルーム」で機能しています。最終的には、Pythonからすべてのインタープリター再帰を除去することを目指しています。Stacklessにはまだ、再帰を行う部分があります。特に、方式の定義済み__xxx__ メソッドは、すべてそうなっています。この最終目標を達成するのはとても難しいことです。そのためには、かなり多くのものを変更したり、新しい命令コードを追加したり、特定の内部呼び出しシーケンスをアンロールしたり、ということが必要になるからです。


参考文献



著者について

David Mertz photo

David Mertzは、ニーチェを傍らに、これらが昔の言語学者の思想なのだと書きたいのですが、その嘘は自ずと化けの皮がはがれることでしょう。ただ、おそらく彼の(まさしくここで只で宣伝してもらえる)近刊書Text Processing in Pythonは、いつの日にか、言語学のサイバー版と間違えられることになるのではないでしょうか。Davidのメール・アドレスはmertz@gnosis.cx です。その生活は、http://gnosis.cx/publish/ でじっくり観察できます。今回のコラム、以前のコラム、あるいは今後のコラムについて、ご意見やご提案があればお寄せください。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


    日本IBMについて プライバシー お問い合わせ