PythonとLispの関係について

Paul Prescod


日本語訳:Shiro Kawai (shiro @ acm.org)
これは、 Paul Prescod:On the Relationship Between Python and Lisp を、原著者の許可を得て翻訳・公開するものです。

2002/06/02 翻訳公開


Lispは時代のはるか先を行っていた。 Lispは最初の高級言語だったから、それ以降に現れた良いものは全てLispの再発明だ、 と信じたくなる人々がいる。 JavaはLispだ。XMLもLispだ(違うのだが)。 そして今度は、PythonはLispだそうだ。

有名なLispエキスパートである Paul Grahamが提示した話はこうだ。 彼が議論に選んだ3つの言語、Java、Perl、Pythonのうち、 PythonはPerlより(ポピュラーではないにせよ)クールだし、 PerlはJavaより(ポピュラーではないにせよ)クールだ、 なぜならPythonが3つのうちで最もLispに近いからだ。 残念ながら、Pythonはまだ成熟しきってないLispのようなもので、 そのうち完全なLispっぽさを備えるだろう。 でも、今CommonLispが使えるのに、何でPythonがLispになるのを待つんだい。

あなたがLispプログラマなら、思わずつりこまれてしまうような話だ。 だが、これは真実ではない。

Grahamは、PerlはJavaよりクールで、PythonはPerlよりクールだと言う。 どこかのグループでは、多分そうなのだろう。GrahamはSlashdotがPerlで書かれているというのを 例に出している。しかし、それならCで書かれているAdvogatoはどうだ。 3つの全ての言語を使って書かれている、数々のクールなP2Pソフトウェアはどうなんだ。 PerlはJavaより古く、一度は「次に来る大きな言語」だと思われていたということを 考えれば、プログラマがJavaよりPerlを「クール」と考えているという統計的な証拠を 見付けるのは非常に難しいだろう。たぶん、 Javaは「業界標準」となって数年経つ(したがって、 スパイスガールズがクールでないのと同じ理由でクールではない)のに対し、 Perlはまだ一種アングラで(したがってアンビエントがクールなのと同じで)クールだ、 とかいうことなんだろう。 PythonはPerlよりもっとアングラだ(だからもっとクールだって?) Grahamが示してみせたのは、Lispに近付けば近付く程言語はアングラになるってことだったの かもしれない。ただ、彼はLispに近さに関して議論を逆にしているようだ。

Grahamは彼自身、(彼の例の中で)Perlのクロージャのセマンティクスは PythonのそれよりもLispに多くを負っていると示している。 それなら、PythonがPerlよりLispに近いという証拠はどこにあるんだ。 実際、PerlはPythonよりももっと意識的にLispの機能を借用してきた。 PerlのLisp的な機能はPerlのコミュニティの中では好まれているが、 Pythonコミュニティではそのような機能について愛憎半ばしている。 これについてはすぐ後で述べる。

PythonはLispの方向へとは成長していない。 Lispに直接影響を受けたPythonの機能はPythonの歴史の非常に初期の段階で追加された。 Guidoは当時、言語設計者として始めたばかりで、 だから「NO」という習慣をまだ身に付けていなかったんだ。 人々が、他の言語からこんなクールな機能を持って来れるよと言ったら、 彼はそのもたらす結果をあまり考えずに取り込んでいた。 最初の数年間、それらの機能は非常に浮いていた。 他のPythonの改善により、最近ではそれらの機能もそれほど浮いてはいないが、 同時に、Pythonの他の新しい機能のおかげで、 それらの機能はあまり重要ではないし使いみちも無くなって来ている。

実際、以下の機能のいくつかまたは全てについて、 それを非推奨にしようという提案が出されている(それほど優先度は高くないが): "apply" (これは現在は第一級の構文となった)、"map"、 "filter" (これはいつもリストの内包表記で置き換えられる)、 "reduce" (forループで置き換えられる)、 そして "lambda" (名前付き関数で置き換えられる)。 これらは明日すぐ取り除かれるというわけではないだろう (悪口メイルを私に送って来ないように)。 だが、これらが削除候補として議論されたという事実がとりもなおさず、 PythonをよりLisp風にしようという動きは無いということを示している。 むしろ、その逆の方向に行くのが好まれているようだ。 (少なくとも、私の意見では "lambda" という名前を持ち込んだのは恐るべき間違いだった)。

Pythonは成長している。しかしLispへ向かってではない。 Pythonの人気が出て来るにしたがって、 他の言語の熱狂的愛好家がPythonはその言語の子孫だと言い出すだろう (「アレクサンダー・グレアム・ベルはカナダ人だった」症候群と呼ぼう)。 Pythonは実は小さなLispだ、とGrahamは言う。Haskellプログラマは、 いやPythonはリストの内包表記といくつかの遅延評価メカニズムを備えているから 小さなHaskellだと言うだろう。遅延ジェネレータを備えたことで、 PythonはよりIconに近付いているとIconプログラマは言うだろう。 Smalltalkプログラマは、メタクラスとユニットテスト機能、 そして新しいメソッド解決順序に注目するかもしれない。 警告、ログ、そして例外処理機構はJavaに最も近いかもしれない。 10年後には、Pythonは(CommonLispも含む)これらの言語からより多くのアイディアを もらっているだろうし、そのうちのいくつかはこれらの言語の再び取り込まれているかも しれない。しかし、Pythonがこれらの言語の特定の一つへ向かって成長して欲しいと思うなら、 長い、長い時間を待たねばならないだろう。

Pythonの最近のいくつかのバージョンについては、 Lispの影響は全ての言語のうちで最も小さい。 新しい機能のうち、Lispの影響かかろうじて見られる、私が思い付く唯一の機能は ネストしたスコープだ。だがC、C++、Java、Perl、Rubyは皆ネストしたスコープを持っている。 これが「Lispの機能だ」というのは、 (Common Lispではなく)McCarthyのLispが最初の高級言語であり、 他の全ての言語はそこで開発されたものから借りるか再発明をしているかである、 というだけのことに過ぎない。

Grahamの「What made Lisp different」のリストを見たまえ。 彼はPythonがだいたい5つの項目を取ったと書いている。 Cは最初の3つ(条件式、関数ポインタ、再帰)を30年前に取った。 次の2つ(動的型チェックとガベージコレクション)は当時の言語にも見られたが、 最近になるまではCPUの負荷が高すぎるとして主流にはならなかった。 次の3つはPythonが実装していないものだ。これに関して興味深いのは、 その3つはハードウェアコスト無しで実装できるということだ。 要するにそれらの機能は、一般的なプログラミング言語の世界で、 そしてとりわけGuidoによって、実装しないことを選択されたのだ。

プログラマは深くネストした式は好まない。 彼らは、式の値に名前が振られることを奨励する言語を好む。 文と式の区別はそれを奨励する(時には要求する)。 シンボル型は悪い考えではないが、インターンされた文字列があればほとんど利点はない。 LispのS式表記は、声高に、はっきりと、過去半世紀の間拒否されてきた。

要するにGrahamは、新しい言語は かつて主流になるには計算負荷が高すぎると判断された Lispの機能を成長に従い取り込んでいるから、 ハードウェアとコンパイラ技術が追い付いた今、 Lispが主流になりそこねた機能までもそれらの言語が取り込むだろうと予測しているのだ。

彼のリストの最後の機能については判断を保留する。 Pythonは彼のいう3つの評価モードのうちの2つを実装している。 実行時の評価と、実行時の読み込みだ。残りの1つはコンパイル時の評価(マクロ)だ。 Pythonはいつの日か、おそらくDylanのそれを基にしてマクロを取り込むかもしれない。 Pythonはまだ、Lispファミリーの言語から学ぶところがある (そして同じく、Smalltalkから、Haskellから、Iconから、Eから、Ozから、…)。 秘密は、成功した部分だけを取って残りは置いておくことだ。 あなたがLispプログラマでないことを選んだとしたら、 私の言いたいことはわかってくれるだろう。

「アキュムレータ」小ベンチマーク

GrahamはPythonに比べたLispの「力」を小さなコード片を比べることで示してみせた。 CでFortranをプログラムするのがうまくいかないように、 PythonでLispをプログラムするのもうまくいきはしない。当然のことだ。

「値を累積して結果を必要に応じて返す『もの』を作れ」という 現実の世界の問題を提示するかわりに、 Grahamはその「もの」は関数でなければならないとしている。 明らかにこれは関数が抽象化のメカニズムの主体である言語で一番うまく行く。 しかし、Pythonでは関数とオブジェクトを共にプリミティブとして持っている。 Pythonではこの場合に適切な抽象化のメカニズムはオブジェクトであり、関数ではない。 オブジェクトはいくつかの理由から良い選択である。

上に述べたような作法を使うことは、Pythonプログラマがお互いのコードを 理解する助けになる。「入力引数が無いって? だったらこの関数は状態無しだな」。 「値を返す関数? これは多分副作用無しだな」。 ところで、このような理解こそが、 オブジェクトと関数の両方を第一級の型として持つのが言語にとって良いということを 示している。

Grahamが問題を「内部に更新可能な状態を持つ関数」と定義したとたん、 彼はPythonのオブジェクト指向モデルから、 (そして純粋な関数型プログラミングからも)足を踏み出してしまったのだ。 Pythonは確かに書き換え可能な状態を持つ関数を作る手段を色々持っているが、 Pythonプログラマはそれを当てにして問題を考えないし、考えるべきではない。

したがって、 その特定の定式化においてPythonの構文的サポートが弱いことは驚くに当たらない。 以下が、同様の問題における慣用的なPythonの書法である。

class Accumulator:
    def __init__(self, start):
        self.val = start

    def incr(self, amount):
        self.val += amount

    def decr(self, amount):
        self.val -= amount

    # not strictly necessary but makes some programmers warm and fuzzy
    def getValue(self):
        return self.val

val = Accumulator(5)
val.incr(10)
val.incr(11)
val.decr(5)
print val.getValue()

CommonLisp版の機能にわざと限定するならば、答えはだいたい5つの文あるいは行の コードになる (CLにおける5つの論理的な文と比較して)。

Lispギークの何人かはPythonを気に入らないだろう。でもあなたは気に入るかもしれない

昨日、私の妻(駆け出しの写真家)が言った。 「私の知ってるたくさんの(大多数の?)プロの写真家はマッキントッシュを使っているわ」。 私はつい、学位に関するちょっとした争いの機会に乗ってしまった。 「そうさ、マッキントッシュはいつだって芸術指向の連中に好まれて来たさ。 たくさんの綺麗なボタンがついているからね」。 同じ日に、しばらくして、私はもう少し真面目になって彼女に言った。 「もしマッキントッシュが君の写真に役立つなら、買ってもいいよ。 私もそれに埋め込まれたUnixのフレームワークが見たいからね。 マッキントッシュはギークの間でもとても人気が出て来ているんだ」 彼女は答えた。「あら、あなたマッキントッシュは芸術家気取りだけのためのものだって 言わなかった?」

最初の文を口にした時、私は1990年代の思考パターンだった。 1990年代には、オペレーティングシステムは使うのが簡単か、 高機能で洗練されているかで、両方を備えるということは有り得なかった。 しかし世紀の終りには、この2分法はどんどん意味をなさなくなっていった。 Linuxはぴかぴかのボタンを備えるようになった。WindowsにはPerlやGCC、bashといった Unixのツールが移植された。そしてマッキントッシュのOS Xがやって来て、 ファミリーセダンとレースカーの両方を同時にやってのけるという すばらしい仕事を成し遂げた。PythonはMac OS Xのプログラミング言語だ。 Pythonは駆け出しのプログラマにも、「普通の」プログラマにも、 そして言語ギークにも同時に好まれ、使われるように設計されている。

Paul Grahamは彼のいくつもの記事の中で、そんなことは不可能だと示唆している。 彼は自動車のアナロジーを使って、彼の新しい言語、Arcは ポルシェになる、 と臆面もなく述べている。最初は使うのが難しいが、長い目で見ればより「パワフル」だと。 そこに置かれている仮定は、最初に使う時も簡単で長い目で見てもパワフルなように 言語を設計するなんて不可能だということだ。 結局、何かが十分に長い間成し遂げられないと、それは不可能だと思われがちなんだ。

ファミリーセダンとレースカーを同時に満たすのは物理法則のせいで不可能だ。 だがソフトウェア設計において、不可能ということはほとんど無い。 言語にせよオペレーティングシステムにせよワードプロセッサにせよ、 3つの全てのクラスのユーザに受け入れられるように設計するになこうすれば良い。

この最後の項目を見て、「ほら、思った通りだ、全ての人に対して全てを提供することは できないじゃないか」って言うかも知れない。その通りさ。そんなことは出来はしない。 新しいマッキントッシュをブートした時、 私はアイコンをぴかぴかさせるのにCPUが浪費されることに不愉快さを覚えるだろう。 でも私と妻とが同じコンピュータを使えるという点が、 両方のために設計されたコンピュータの持つちょっとしたイライラする点よりもずっと 大事なんだ。

同様に、大きくて複雑な言語よりPythonを使う利点を考えてみよう。

tim Berners-Leeは毎日毎日、Webに関する壮大な計画を考え、 危険な政治的駆け引きを行っている。 彼がちょっとハックしたいなと 思ったら、彼は自分の頭の「1ページ」に収まって、必要な時にすぐにスワップインして またすぐにスワップアウトできるような言語を使いたがるだろう。 Pythonがその言語だ。そして私Pythonを使うことで、 セマンティックなWebプロセッシングを行いたい時に彼のコードを再利用することができる。 (ちょうど私の書いているUnixコードをテストするのに妻のIMacを使えるようなものだ)。 Paul Grahamは、「大衆向け」に設計された言語は実のところ 「間抜け」向けに設計されているんだといっている。 私の観察によると、どうやらこの惑星上で最も賢い人々は プログラミングに関しては(あるいは、動的プログラミング言語に関しては) 間抜けということになるらしい。 が、私は彼らと同じ言語を(そしてコードも!)共有できることに喜びを感じる。

私は普通、日常の多くの時間をPythonに費す。 だが大抵のプロフェッショナルプログラマは、Pythonがもっと業界を支配するまでは Pythonに多くの時間を割くわけにはいかないだろう。 それまでは、彼らはPythonと仕事に使う言語との間を行ったり来たりすることになる。 Pythonはそれが容易に出来るように設計されている。 昼の間、彼らは会計ソフト をがりがりと書き、夜には分散オブジェクト指向ファイルシステム をハックする。直観的に名付けられた関数名は、Pythonを頭の中にスワップイン するのを容易にする。しばらく言語から離れていれば、我々誰しもが間抜けになる のだから、間抜けのために選択された全ての機能は実際ハイエンドの開発者をも 利することになるのだ。

私は自分のコードを、その分野でのエキスパートとされる「間抜け」達と共有することで 報酬を得ている。Pythonを使うことで、私は私のコードを彼らがVBから使えるように COMオブジェクトに包むようなことをしなくて済む。 私は、非エキスパートのためだけに設計されたがたがたの言語でプログラムを書かないで 済むし、彼らはエキスパートのためだけに書かれた難しい言語を学ばなくても済む。 私達は同じ言語で会話できるのだ。 彼らは私の書いたコードを読むことが出来るし、必要とあらばメインテインすることだってできる。

純粋に利他的な観点から、私は自分の書いたコード(特にオープンソースのコード)が 高校生や他の プログラミング初心者 の課題になることに喜びを感じる。

複雑さの大部分は取り除かれるか隠されるかしているから、 ハードコアなギークでさえ、最小限で単純な何かを使うことにある種の美学的な喜びを 見出している。

もし、ローエンドのプログラマに合わせたために高い代償を払っているのだと しても、どうやらそれは私の心を変えさせるには足りないようだ。 だがPythonは、Lispも含む他の言語に深い経験を持つ人々の間でも明らかに人気を得ている。 例えば、Eric RaymondPeter NorvigDan Connolly、そして Erann Gatといった人々だ。 私はSchemeとPythonを知っているがCommon Lispは知らない。 Paul GrahamはCommon LispとSchemeを知っているがPythonは知らない。 我々を信頼するな。上に挙げた人々は少なくとも一つのLisp (通常はCommonLisp) と Pythonを知っている。彼らは胸に一物を抱いているわけじゃない。 そして彼らは、Pythonに移行したことで何か大きなものを失ったとは思っていないようだ。

Pythonはまだ最も人気のある言語では無いが、 宣伝をする主体もなく、大きなスポンサー会社も無く、 (JavaとJavascriptがNetscapeに含まれていたように)それが含まれたキラーアプリ1 も無いにもかかわらず、急速に人気を得つつある。 利用者の満足に基づいて強く伸びて来ているもうひとつの言語はRubyだ。 Perlは、Perl 6がリリースされた時にこのリストに再び加わるかもしれない。

全てのレベルにわたるプログラマが、「Pythonはちょうど良いところで妥協している」 と感じているように思える。もしあなたが、Lispが(再び)世界を支配するのを待てなければ、 Pythonもしくは他のいわゆる「スクリプト言語」と呼ばれるものを調べてみると良い。 Pythonはたぶん、あなたが使っている間にも成長して変わって行くであろうことは 断っておかねばならない。またそれはどちらかというと有機的に成長するため、 誰も (Paul Grahamでも) それが正確にどういうふうに成長して行くかは予測できないだろう。

1. Zopeはアプリケーションでありキラーであるかもしれないが、 Pythonのキラーアプリとは言えないだろう。 PHPユーザの大部分がApacheを使い、 JavaScript(及び初期のJava)プログラマの大部分がwebブラウザを使っている(いた) のと同じようには、 Pythonの大多数のプログラマがZopeを使っているという状態にはなっていない。