Loading...

百年の言語

Original

2003年4月

(このエッセイは、PyCon 2003 の基調講演から抜粋したものです。)

100 年後の暮らしがどうなるかを予測するのは難しい。確実に言えることはほんのわずかだ。誰もが空飛ぶ車を運転し、何百階建ての建物も建てられるよう都市計画法が緩和され、ほとんどの時間は暗くなり、女性は皆武術の訓練を受けているだろう。ここで、この絵の細部を 1 つ取り上げてみたい。空飛ぶ車を制御するソフトウェアを書くのに、どのようなプログラミング言語が使われるのだろうか。

これについて考える価値があるのは、実際にこれらの言語を使用できるようになるからというよりも、運が良ければ、この時点からそこまでの道のりで言語を使用することになるからです。

言語も種と同じように進化の樹形を形成し、行き止まりが至る所に枝分かれしていくと私は考えています。これはすでに起きています。コボルは、一時人気があったにもかかわらず、知的な後継者がいないようです。これは進化の行き止まり、つまりネアンデルタール人の言語なのです。

私は Java についても同様の運命を予想しています。時々、「Java が成功する言語にならないとどうして言えるのですか? Java はすでに成功する言語です」というメールが届きます。そして、成功を Java に関する書籍 (特に個々の書籍) が占める棚のスペースや、就職するために Java を学ばなければならないと考えている学部生の数で測るなら、成功であることは私も認めます。Java が成功する言語にならないと言うとき、私はもっと具体的なことを意味しています。つまり、Java は Cobol のように進化の行き止まりになるということです。

これは単なる推測です。間違っているかもしれません。ここでの私の主張は、Java を批判することではなく、進化の樹形図の問題を提起し、人々に「言語 X は樹形のどこにあるのか」と尋ねてもらうことです。この質問をする理由は、100 年後に私たちの幽霊が「そう言っていただろう」と言うためだけではありません。主要な枝の近くに留まることは、現在プログラミングするのに適した言語を見つけるための有用なヒューリスティックだからです。

いつの時代も、進化の樹の主枝の上にいるのが一番幸せでしょう。ネアンデルタール人がまだたくさんいた時代でも、その一人になるのは大変だったに違いありません。クロマニヨン人が絶えずやって来て、殴り、食べ物を盗んでいたでしょう。

100 年後の言語がどのようなものになるかを知りたいのは、今、木のどの枝に賭けるべきかを知るためです。

言語の進化は、分岐が収束する可能性があるため、種の進化とは異なります。たとえば、Fortran の分岐は、Algol の子孫と融合しているようです。理論上は種にもこれは可能ですが、細胞よりも大きい種ではおそらく起こっていないでしょう。

言語の場合、可能性の空間が狭いことと、突然変異がランダムではないことが、収束が起きやすい理由です。言語設計者は、他の言語のアイデアを意図的に取り入れます。

プログラミング言語の進化がどこに向かうのかを考えることは、言語設計者にとって特に有益です。それに応じて方向を定めることができるからです。その場合、「メイン ブランチに留まる」ことは、良い言語を選択する方法以上のものになります。それは、言語設計について正しい決定を下すための経験則になります。

どのプログラミング言語も、公理の役割を果たす一連の基本演算子と、原理的にはこれらの基本演算子を使って記述できる言語の残りの部分の 2 つの部分に分けることができます。

言語が長期的に生き残るためには、基本演算子が最も重要な要素だと思います。残りは変更できます。家を買うときにまず場所を考慮するというルールに似ています。他のすべては後で修正できますが、場所を修正することはできません。

公理が適切に選択されるだけでなく、その数が少数であることも重要だと私は思います。数学者は公理について常にこのように感じてきました。つまり、公理の数は少ないほど良いということです。そして、彼らは正しい考えを持っていると思います。

少なくとも、言語の核心を詳しく調べて、除去できる公理がないか調べるのは、役に立つ練習になるはずです。私は、ずぼらな人間としての長いキャリアの中で、くだらないものがくだらないものを生むことを知りました。そして、ソフトウェアだけでなく、ベッドの下や部屋の隅でも、この現象が起きるのを見てきました。

進化の樹形図の主な枝は、最も小さく、最もクリーンなコアを持つ言語を通るのではないかという予感がします。言語自体で記述できる内容が多ければ多いほど良いのです。

もちろん、100 年後のプログラミング言語がどうなっているかを尋ねること自体、大きな仮定を立てていることになります。100 年後に私たちはプログラムを書いているでしょうか? コンピューターに何をしてほしいかを指示するだけでは済まないのでしょうか?

今のところ、その分野では大きな進歩はありません。私の推測では、100年後も、人間は私たちがプログラムとして認識できるものを使ってコンピューターに何をすべきかを指示するでしょう。現在私たちがプログラムを書いて解決しているタスクが、100年後にはプログラムを書く必要がなくなるかもしれませんが、今日私たちが行っているようなタイプのプログラミングは、今でもかなりあると思います。

100 年後のテクノロジーがどうなっているかを誰もが予測できると考えるのはおこがましいように思えるかもしれません。しかし、私たちにはすでに 50 年近い歴史があることを忘れないでください。過去 50 年間の言語の進化の遅さを考えると、100 年先を見据えることは理解できる考えです。

言語は実際にはテクノロジーではないため、ゆっくりと進化します。言語は表記法です。プログラムとは、コンピューターに解決してもらいたい問題を形式的に記述したものです。そのため、プログラミング言語の進化の速度は、輸送や通信などの進化速度よりも、数学表記法の進化速度に近いと言えます。数学表記法は進化しますが、テクノロジーに見られるような大きな飛躍的進歩ではありません。

100 年後のコンピューターが何であれ、今よりはるかに高速になると予測しても間違いないでしょう。ムーアの法則が今後も続くと、コンピューターの速度は 74 京 (73,786,976,294,838,206,464) 倍速くなります。これはちょっと想像しにくいことです。実際、速度に関して最もありそうな予測は、ムーアの法則が機能しなくなるということかもしれません。18 か月ごとに 2 倍になるはずのものは、いずれ何らかの根本的な限界にぶつかると思われます。しかし、コンピューターの速度がはるかに速くなることは間違いありません。たとえ 100 万倍しか速くならなかったとしても、プログラミング言語の基本ルールは大きく変わるはずです。とりわけ、現在では遅い言語と見なされている言語、つまりあまり効率的なコードを生成しない言語が活躍する余地が増えるでしょう。

それでも、一部のアプリケーションでは依然として速度が求められます。コンピューターで解決したい問題の中には、コンピューターによって生成されるものもあります。たとえば、ビデオ画像を処理する速度は、別のコンピューターがそれを生成できる速度に依存します。また、本質的にサイクルを吸収する容量が無制限である別の種類の問題もあります。それは、画像のレンダリング、暗号化、シミュレーションです。

一部のアプリケーションがますます非効率になる一方で、他のアプリケーションがハードウェアが提供できるすべての速度を要求し続ける場合、コンピュータの高速化は、言語がこれまで以上に幅広い効率性をカバーする必要があることを意味します。これはすでに起きています。いくつかの人気のある新しい言語の現在の実装は、過去数十年の基準からすると驚くほど無駄が多いです。

これはプログラミング言語に限ったことではありません。一般的な歴史的傾向です。テクノロジーが進歩するにつれ、各世代は前の世代が無駄だと考えていたことを実行できるようになります。30 年前の人々は、私たちがいかに気軽に長距離電話をかけているかに驚くでしょう。100 年前の人々は、ある日、ボストンからニューヨークまでメンフィス経由で小包が届くことにさらに驚くでしょう。

今後 100 年間で、より高速なハードウェアによってもたらされる余分なサイクルがどうなるかは、すでにお伝えできます。それらはほぼすべて無駄になるでしょう。

私がプログラミングを学んだのは、コンピュータのパワーが乏しかった頃です。Basic プログラムからすべてのスペースを削除して、4K TRS-80 のメモリに収まるようにしたのを覚えています。同じことを何度も繰り返してサイクルを消費する、途方もなく非効率なソフトウェアのすべてを考えると、ちょっと気持ちが悪いです。しかし、私の直感は間違っていると思います。私は貧乏な家庭で育ち、医者に行くなど、重要なことにさえお金を使うことに耐えられない人のようです。

ある種の無駄は本当に不快です。たとえば、SUV は、燃料が尽きることがなく、汚染物質をまったく発生させないとしても、間違いなく不快です。SUV が不快なのは、不快な問題の解決策だからです (ミニバンをより男性らしく見せる方法)。しかし、すべての無駄が悪いわけではありません。今ではそれをサポートするインフラストラクチャがあり、長距離通話の時間を数えることは些細なことに思えてきます。リソースがある場合は、相手がどこにいても、すべての電話を 1 つの種類のものとして考える方がエレガントです。

無駄には良いものと悪いものがあります。私が興味があるのは良い無駄、つまり、より多くを費やすことでよりシンプルな設計を実現できる無駄です。新しい高速ハードウェアから得られるサイクルを無駄にする機会をどのように活用するのでしょうか。

スピードへの欲求は、貧弱なコンピュータとともに、私たちの中に深く根付いているため、それを克服するには意識的な努力が必要です。言語設計では、効率を犠牲にして利便性を少しでも高められる状況を意識的に探す必要があります。

ほとんどのデータ構造は、速度のために存在します。たとえば、今日の多くの言語には、文字列とリストの両方があります。意味的には、文字列は多かれ少なかれ、要素が文字であるリストのサブセットです。では、なぜ別のデータ型が必要なのでしょうか。実際には、必要ありません。文字列は効率性のためだけに存在します。しかし、プログラムを高速化するためのハックで言語の意味を乱雑にするのは無意味です。言語に文字列があることは、時期尚早な最適化の例のようです。

言語の核心を公理の集合と考えると、効率だけを考えて、表現力を高めない公理を追加するのは明らかに不適切です。効率は重要ですが、それが正しい方法だとは思いません。

この問題を解決する正しい方法は、プログラムの意味を実装の詳細から切り離すことだと私は思います。リストと文字列の両方を持つのではなく、リストだけを持ち、必要に応じて文字列を連続したバイトとしてレイアウトできるようにコンパイラーの最適化アドバイスを提供する方法を用意します。

ほとんどのプログラムでは速度は重要ではないため、通常はこのような細かい管理に煩わされる必要はありません。これは、コンピューターが高速化するにつれてますます真実になります。

実装についてあまり言及しないことで、プログラムの柔軟性も向上します。プログラムの作成中に仕様が変更されることは避けられないだけでなく、望ましいことです。

「エッセイ」という言葉は、フランス語の動詞「essayer」に由来しており、「試みる」という意味です。エッセイは、本来の意味では、何かを理解しようとして書くものです。これはソフトウェアでも同じです。著者が書き始めたときに、自分が何を書こうとしていたのか正確にはわからなかったという意味で、最も優れたプログラムのいくつかはエッセイだったと思います。

Lisp ハッカーは、データ構造を柔軟に扱うことの価値をすでに知っています。私たちは、プログラムの最初のバージョンを、すべてをリストで実行するように書く傾向があります。これらの最初のバージョンは、驚くほど非効率な場合があり、何をしているか考えないように意識的に努力する必要があります。少なくとも私にとっては、ステーキを食べるときに、それがどこから来たのか考えないように意識的に努力する必要があるのと同じです。

100 年後のプログラマーが何よりも求めているのは、信じられないほど非効率的なプログラムのバージョン 1 を最小限の労力で作成できる言語です。少なくとも、現代の言葉で言えばそのようになります。プログラマーが求めているのは、プログラミングが簡単な言語です。

非効率なソフトウェアはひどいものではありません。ひどいのは、プログラマーに不必要な作業をさせる言語です。プログラマーの時間を無駄にすることが本当の非効率であり、マシンの時間を無駄にすることではないのです。これは、コンピューターが高速化するにつれてますます明らかになるでしょう。

文字列を取り除くことは、すでに検討に値することだと思います。 Arcでそれを実現しましたが、成功したようです。正規表現として記述するのが難しい操作も、再帰関数として簡単に記述できます。

データ構造のフラット化はどこまで進むのでしょうか。良心的に視野が広がった私でさえも驚くような可能性を思いつきます。たとえば、配列はなくなるのでしょうか。結局のところ、配列はキーが整数のベクトルであるハッシュ テーブルのサブセットにすぎません。ハッシュ テーブル自体をリストに置き換えるのでしょうか。

それよりもさらに衝撃的な見通しがあります。たとえば、マッカーシーが 1960 年に説明した Lisp には数値がありませんでした。論理的には、数値をリストとして表すことができるため、数値という別の概念を持つ必要はありません。整数 n は n 個の要素のリストとして表すことができます。この方法で数学を行うことができます。これは耐え難いほど非効率的です。

実際に数値をリストとして実装することを提案した人は誰もいませんでした。実際、マッカーシーの 1960 年の論文は、当時はまったく実装されることを意図していませんでした。それは理論的な演習であり、チューリング マシンのよりエレガントな代替物を作成する試みでした。誰かが思いがけずこの論文を取り上げ、実用的な Lisp インタープリタに翻訳したとき、数値はリストとして表現されることはなく、他のすべての言語と同様に 2 進数で表現されました。

プログラミング言語は、基本的なデータ型として数字を排除するところまで行くことができるでしょうか? これは、真剣な質問というよりは、未来とのチキン ゲームの方法として尋ねています。これは、抵抗できない力が動かせない物体に出会うという仮説的なケースのようなものです。ここでは、想像を絶するほど非効率的な実装が、想像を絶するほど膨大なリソースに出会うのです。なぜできないのかわかりません。未来はかなり長いです。コア言語の公理の数を減らすために何かできることがあるなら、t が無限大に近づくにつれて、その側に賭けるべきであると思われます。そのアイデアが 100 年経ってもまだ耐えられないと思われるなら、1000 年経ってもそうではないかもしれません。

念のため明確にしておきますが、私はすべての数値計算が実際にリストを使用して実行されることを提案しているわけではありません。実装に関する追加の表記法の前に、コア言語をこのように定義することを提案しています。実際には、ある程度の計算を実行したいプログラムは、おそらく数値を 2 進数で表すでしょうが、これは最適化であり、コア言語のセマンティクスの一部ではありません。

サイクルを浪費するもう 1 つの方法は、アプリケーションとハードウェアの間に多くのソフトウェア レイヤーを配置することです。これもすでに起こっている傾向です。最近の言語の多くはバイト コードにコンパイルされています。Bill Woods はかつて私に、経験則として、解釈レイヤーごとに速度が 10 倍になると言いました。この追加コストによって柔軟性が得られます。

Arc の最初のバージョンは、この種のマルチレベルの遅さの極端な例でしたが、それ相応の利点がありました。これは、Common Lisp の上に書かれた古典的な「メタ循環」インタープリタで、McCarthy の元の Lisp 論文で定義された eval 関数と明らかに類似していました。コード全体はわずか数百行だったので、理解し、変更するのは非常に簡単でした。私たちが使用した Common Lisp、CLisp 自体は、バイトコード インタープリタの上に実行されます。つまり、ここでは 2 つのレベルのインタープリタがあり、そのうちの 1 つ (最上位) は驚くほど非効率的でしたが、言語は使用可能でした。かろうじて使用可能だったことは認めますが、使用可能でした。

ソフトウェアを複数のレイヤーとして記述することは、アプリケーション内でも強力なテクニックです。ボトムアップ プログラミングとは、プログラムを一連のレイヤーとして記述し、各レイヤーが上位のレイヤーの言語として機能することを意味します。このアプローチでは、より小さく、より柔軟なプログラムが作成される傾向があります。また、再利用性という究極の目標への最善の道でもあります。言語は定義上、再利用可能です。アプリケーションをそのタイプのアプリケーションを記述するための言語にプッシュダウンできるほど、ソフトウェアの再利用性は高まります。

どういうわけか、再利用性という概念は 1980 年代にオブジェクト指向プログラミングに結び付けられ、反証となる証拠がいくらあっても、この概念を覆すことはできないようです。しかし、一部のオブジェクト指向ソフトウェアは再利用可能ですが、再利用可能にしているのは、オブジェクト指向性ではなく、ボトムアップ性です。ライブラリについて考えてみましょう。ライブラリは、オブジェクト指向スタイルで記述されているかどうかに関係なく、言語であるため再利用可能です。

ところで、私はオブジェクト指向プログラミングの終焉を予測しているわけではありません。特定の専門分野を除いて、優れたプログラマーにはあまりメリットがないと思いますが、大規模な組織にとっては魅力的です。オブジェクト指向プログラミングは、スパゲッティ コードを記述するための持続可能な方法を提供します。これにより、一連のパッチとしてプログラムを蓄積できます。

大規模な組織では、常にこのようにソフトウェアを開発する傾向があり、これは今日と同じように 100 年後も当てはまると私は予想しています。

将来について語るのであれば、並列計算についても語るべきです。なぜなら、このアイデアはそこに生きているように思われるからです。つまり、いつ語ろうとも、並列計算は将来起こることのように思えます。

将来はこれに追いつくでしょうか? 並列計算は少なくとも 20 年間、差し迫ったものとして話題になっていますが、これまでのところプログラミングの実践にはあまり影響していません。それとも、影響していないのでしょうか? すでにチップ設計者はこれについて考える必要があり、マルチ CPU コンピューターでシステム ソフトウェアを作成しようとしている人々も同様に考えなければなりません。

本当の疑問は、並列処理は抽象化のどの段階まで進むのかということです。100 年後には、並列処理はアプリケーション プログラマーにも影響を与えるでしょうか。それとも、コンパイラー作成者が考えるものであって、アプリケーションのソース コードでは通常目に見えないものになるのでしょうか。

1 つありそうなのは、並列処理の機会のほとんどが無駄になるということです。これは、与えられた余分なコンピュータ パワーのほとんどが無駄になるという、より一般的な予測の特殊なケースです。基盤となるハードウェアの驚異的な速度と同様に、並列処理は明示的に要求すれば利用可能になるが、通常は使用されないものになると予想しています。これは、特殊なアプリケーションを除いて、100 年後に実現する並列処理は大規模な並列処理ではないことを意味します。一般的なプログラマーにとっては、すべてが並列で実行されるプロセスを分岐できるようなものになると思います。

そして、これは、データ構造の特定の実装を要求するのと同様に、プログラムのかなり後期、つまり最適化を試みるときに行うものになります。バージョン 1 では、通常、並列計算から得られる利点は無視されますが、これはデータの特定の表現から得られる利点も無視するのと同じです。

特殊な種類のアプリケーションを除いて、並列処理は 100 年後に作成されるプログラムに浸透することはありません。浸透しているとすれば、それは時期尚早な最適化です。

100 年後にはプログラミング言語がいくつあるでしょうか? 最近、新しいプログラミング言語が大量に登場しているようです。その理由の 1 つは、ハードウェアの高速化により、プログラマーがアプリケーションに応じて速度と利便性の間でさまざまなトレードオフを行えるようになったことです。これが実際の傾向であれば、100 年後のハードウェアによってこの傾向はさらに強まるはずです。

それでも、100年後には広く使われている言語はほんのわずかかもしれません。私がこう言う理由の1つは楽観的なことです。本当にうまくやれば、遅いバージョン1を書くのに理想的でありながら、コンパイラに適切な最適化アドバイスを与えれば、必要に応じて非常に高速なコードも生成できる言語を作ることができるようです。ですから、私は楽観的なので、許容できる効率と最大効率の間には大きなギャップがあるにもかかわらず、100年後のプログラマーは、そのほとんどをカバーする言語を持っているだろうと予測します。

このギャップが広がるにつれて、プロファイラーの重要性は増すでしょう。現在、プロファイリングにはほとんど注意が払われていません。高速なアプリケーションを実現するには、高速なコードを生成するコンパイラーを書くことだ、と多くの人がまだ信じているようです。許容可能なパフォーマンスと最大のパフォーマンスのギャップが広がるにつれて、高速なアプリケーションを実現するには、一方から他方への適切なガイドを用意することがますます明らかになるでしょう。

言語は少数しかないかもしれないと言うとき、私はドメイン固有の「小さな言語」を含めていません。そのような埋め込み言語は素晴らしいアイデアだと思いますし、普及することを期待しています。しかし、その下にある汎用言語をユーザーが見ることができるほど薄いスキンとして記述されることを期待しています。

将来の言語を設計するのは誰でしょうか? 過去 10 年間で最もエキサイティングなトレンドの 1 つは、Perl、Python、Ruby などのオープンソース言語の台頭です。言語設計はハッカーによって引き継がれています。これまでの結果は雑然としていますが、期待が持てます。たとえば、Perl には驚くほど斬新なアイデアがいくつかあります。驚くほど悪いものもたくさんありますが、それは野心的な取り組みに常に当てはまることです。現在の変化の速度では、Perl が 100 年後にどのような進化を遂げるかは神のみぞ知るところです。

できない人が教えるというのは真実ではない (私が知っている最高のハッカーの中には教授もいる) が、教える人ができないことがたくさんあるのは事実である。研究はカーストによる制約を課す。どの学問分野にも、取り組んでもよいテーマとそうでないテーマがある。残念ながら、許容されるテーマと禁じられているテーマの区別は、研究論文で説明されたときにその研究がいかに知的であるかに基づいているのが普通であり、よい結果を得るためにどれほど重要であるかに基づいているのではない。極端な例はおそらく文学だろう。文学を研究している人は、文学を制作する人たちにとって少しでも役に立つようなことはめったに言わない。

科学の分野では状況は改善していますが、実行が許されている種類の作業と、優れた言語を生み出す種類の作業との重なりは、残念なほど小さいです。(Olin Shivers は、これについて雄弁に不満を述べています。) たとえば、静的型付けは真のマクロを排除するように見えるにもかかわらず、型は研究論文の無尽蔵の源のようです。私の意見では、マクロがなければ、どの言語も使う価値がありません。

傾向としては、言語が単に「研究」ではなくオープンソース プロジェクトとして開発されるというだけではなく、コンパイラの作成者ではなく、その言語を使用する必要のあるアプリケーション プログラマによって言語が設計されるという傾向もあります。これは良い傾向のように思えますし、今後も続くと予想しています。

100 年後の物理学はほぼ必然的に予測不可能ですが、100 年後のユーザーにアピールする言語を今設計することは原理的には可能だと思います。

言語を設計する 1 つの方法は、それを翻訳できるコンパイラやそれを実行できるハードウェアがあるかどうかに関係なく、書きたいプログラムをただ書き出すことです。これを行うと、無制限のリソースを想定できます。今日も 100 年後も、無制限のリソースを想像できるはずです。

どのようなプログラムを書きたいでしょうか。最も手間のかからないプログラムであれば何でもかまいません。ただし、そうではありません。プログラミングに関する考え方が、現在使用している言語の影響を受けていない場合は、最も手間のかからないプログラムであれば何でもかまいません。このような影響は非常に広範囲に及ぶため、克服するには多大な労力が必要です。私たちのような怠け者には、最も手間をかけずにプログラムを表現する方法が明らかであると思われるかもしれません。実際、可能性に関する私たちの考え方は、私たちが考える言語によって非常に制限される傾向があり、プログラムのより簡単な定式化は非常に意外に思えます。それは、自然に身につくものではなく、発見しなければならないものです。

ここで役立つコツの 1 つは、プログラムの長さを、それを書くのにどれくらいの労力がかかるかの近似値として使うことです。もちろん、文字数の長さではなく、個別の構文要素の長さ、つまり、基本的には構文解析ツリーのサイズです。最短のプログラムを書くのに最も労力がかからないというのは、必ずしも真実ではないかもしれませんが、それに近いので、あいまいで労力が最も少ない目標よりも、簡潔さという確固たる目標を目指す方がよいでしょう。すると、言語設計のアルゴリズムは次のようになります。プログラムを見て、これをもっと短く書く方法はないかと自問してください。

実際には、架空の 100 年先の言語でプログラムを書くことは、核心にどれだけ近いかによって、さまざまな程度でうまくいくでしょう。ソート ルーチンは今すぐにでも書けます。しかし、100 年後にどのようなライブラリが必要になるかを今予測するのは困難です。おそらく、多くのライブラリは、まだ存在すらしていないドメイン用になるでしょう。たとえば、SETI@home が機能する場合、エイリアンと通信するためのライブラリが必要になります。もちろん、エイリアンが XML で通信できるほど十分に進歩している場合は別ですが。

反対に極端な場合、コア言語を今日設計できるかもしれないと思います。実際、1958 年にはすでに大部分が設計されていたと主張する人もいるかもしれません。

もし 100 年前の言語が今日利用可能だったとしたら、私たちはその言語でプログラミングしたいと思うでしょうか? この質問に答える 1 つの方法は、過去を振り返ることです。もし現在のプログラミング言語が 1960 年に利用可能だったとしたら、それを使いたいと思う人はいたでしょうか?

ある意味、答えはノーです。今日の言語は、1960 年には存在しなかったインフラストラクチャを前提としています。たとえば、Python のようにインデントが重要な言語は、プリンタ端末ではうまく動作しません。しかし、そのような問題を脇に置いて、たとえばプログラムがすべて紙に書かれていたと仮定すると、1960 年代のプログラマーは、現在使用されている言語でプログラムを書くことを好んだでしょうか。

そうだと思います。想像力の少ないプログラマーの中には、プログラムとは何かという概念に初期の言語の遺物が組み込まれていたため、苦労した人もいるかもしれません。(ポインタ演算を行わずにデータを操作するにはどうすればいいでしょうか? goto なしでフローチャートを実装するにはどうすればいいでしょうか?) しかし、最も賢いプログラマーは、現代の言語を持っていれば、問題なくそれらを最大限に活用できたと思います。

もし今、100 年後の言語が存在すれば、少なくとも素晴らしい擬似コードが作れるでしょう。それを使ってソフトウェアを書くのはどうでしょうか? 100 年後の言語は、一部のアプリケーションでは高速なコードを生成する必要があるため、おそらく、ハードウェア上で十分に実行できるほど効率的なコードを生成できるでしょう。100 年後のユーザーよりも多くの最適化アドバイスを提供しなければならないかもしれませんが、それでも最終的に利益になるかもしれません。

ここで、2 つのアイデアが浮かび上がります。これらを組み合わせると、興味深い可能性が示唆されます。(1) 100 年後の言語は、原理的には今日設計できる、(2) そのような言語が存在する場合、今日プログラミングするのに適している、というものです。これらのアイデアをこのように並べてみると、100 年後の言語を今書いてみたらどうだろう、と思わずにはいられません。

言語設計に取り組むときは、そのような目標を持ち、それを意識的に心に留めておくのが良いと思います。車の運転を習うときに教わる原則の 1 つは、ボンネットを道路に描かれた縞模様に合わせるのではなく、遠くのどこかの点を狙って車を合わせることです。次の 10 フィートで何が起こるかだけを気にするとしても、これが正しい答えです。プログラミング言語でも同じことができるし、そうすべきだと思います。

注記

Lisp Machine Lisp は、宣言 (動的変数の宣言を除く) は単なる最適化のアドバイスであり、正しいプログラムの意味は変更しないという原則を具体化した最初の言語であると私は信じています。Common Lisp は、これを明示的に述べた最初の言語であるようです。

この原稿を読んでくれた Trevor Blackwell、Robert Morris、Dan Giffin に感謝します。また、PyCon での講演に招待してくれた Guido van Rossum、Jeremy Hylton、その他の Python チームのメンバーにも感謝します。