言語設計に関する5つの質問
Original2001年5月
(これらは、2001 年 5 月 10 日に MIT で行われたプログラミング言語設計に関するパネル ディスカッションのために作成したメモです。)
1. プログラミング言語は人間のためのものです。
プログラミング言語は、人間がコンピューターと対話する方法です。コンピューターは、曖昧さのない言語であれば、どんな言語でも喜んで話します。高級言語が存在するのは、人間が機械語を扱えないからです。プログラミング言語の目的は、人間の脆弱な脳が大量の詳細に圧倒されないようにすることです。
建築家は、ある種の設計上の問題が他のものよりも個人的な問題であることを知っています。最も明確で抽象的な設計上の問題の 1 つは橋の設計です。そこでの仕事は、主に、最小限の材料で一定の距離を橋で渡ることです。その対極にあるのが椅子の設計です。椅子の設計者は、人間のお尻について考えることに時間を費やさなければなりません。
ソフトウェアも同様に変化します。ネットワークを介してデータをルーティングするためのアルゴリズムを設計することは、橋を設計するのと同じように、抽象的で優れた問題です。一方、プログラミング言語を設計することは、椅子を設計するのと似ています。つまり、人間の弱点に対処することがすべてなのです。
私たちのほとんどは、これを認めたくありません。人間の弱点に迎合するよりも、数学的に優れた優雅さを備えたシステムを設計する方が、私たちの多くにとってはるかに魅力的に聞こえます。そして、数学的な優雅さには役割があります。ある種の優雅さは、プログラムを理解しやすくします。しかし、優雅さはそれ自体が目的ではありません。
言語は人間の弱点に合わせて設計する必要があると私が言うとき、私は言語が下手なプログラマー向けに設計されなければならないと言っているのではありません。実際、最高のプログラマー向けに設計すべきだと思いますが、最高のプログラマーにも限界があります。すべての変数が整数の添え字が付いた文字 x である言語でプログラミングしたい人はいないと思います。
2. 自分自身と友人のためにデザインする。
プログラミング言語の歴史を振り返ると、最も優れた言語の多くはその作者自身が使用するために設計されたものであり、最も劣悪な言語の多くは他の人が使用するために設計されたものであることがわかります。
言語が他の人向けに設計される場合、それは常に特定のグループの人々、つまり言語設計者ほど賢くない人々を対象とします。つまり、あなたに対して上から目線で話す言語が生まれます。Cobol は最も極端な例ですが、多くの言語にこの精神が浸透しています。
これは言語の抽象度とはまったく関係ありません。C はかなり低レベルですが、作者が使用するために設計されたものであり、それがハッカーに好まれる理由です。
下手なプログラマー向けに言語を設計すべきだという主張は、下手なプログラマーのほうが上手なプログラマーより多いというものです。確かにその通りかもしれません。しかし、その少数の上手なプログラマーが、ソフトウェアの不釣り合いに大きい割合を書いています。
私は、「最高のハッカーが好む言語をどう設計するか」という質問に興味があります。これは、「優れたプログラミング言語をどう設計するか」という質問と同じだと思いますが、たとえそうでなかったとしても、少なくとも興味深い質問です。
3. プログラマーに可能な限り多くの制御権を与える。
多くの言語 (特に他の人向けに設計された言語) は、家庭教師のような態度をとります。つまり、ユーザーにとって良くないと思われることをユーザーが行わないように阻止しようとします。私はその逆のアプローチが好きです。つまり、プログラマーにできる限り多くの制御権を与えるのです。
私が初めて Lisp を学んだとき、最も気に入ったのは、Lisp が私を対等なパートナーとして扱ったことです。それまでに学んだ他の言語では、言語と、その言語で書かれた私のプログラムがあり、この 2 つは完全に分離されていました。しかし Lisp では、私が書いた関数やマクロは、言語自体を構成するものとまったく同じでした。必要に応じて言語を書き直すことができました。オープンソース ソフトウェアと同じ魅力がありました。
4. 簡潔さを心がけましょう。
簡潔さは過小評価され、軽蔑さえされます。しかし、ハッカーの心の中を覗いてみると、彼らが簡潔さを本当に愛していることがわかります。たとえば、APL では、わずか数行のコードで素晴らしいことができるとハッカーが楽しそうに語るのを何度聞いたことがありますか? 本当に賢い人々が本当に愛するものは、注目する価値があると思います。
プログラムを短くするためにできることはほとんど何でも良いと思います。ライブラリ関数をたくさん用意し、暗黙的に記述できるものは暗黙的に記述し、構文は簡潔にし、物の名前さえも短くするべきです。
短くすべきなのはプログラムだけではありません。マニュアルも薄くする必要があります。マニュアルの大部分は、説明、留保、警告、特別なケースで占められています。マニュアルを無理やり短くするなら、最良のケースでは、多くの説明を必要とする言語の問題を修正することで短くすることができます。
5. ハッキングとは何かを認める。
多くの人は、ハッキングが数学、あるいは少なくとも自然科学のようなものだと思っています。私はハッキングは建築に似ていると思います。建築は、建築家が倒れない建物を設計しなければならないという意味で物理学に関連していますが、建築家の実際の目標は、静力学に関する発見をすることではなく、素晴らしい建物を作ることです。
ハッカーが好むのは、素晴らしいプログラムを作ることです。そして、たとえそれが研究論文という従来の知的通貨に簡単には結び付かなくても、素晴らしいプログラムを書くことは称賛に値することだということを、少なくとも私たち自身の心の中では忘れてはならないと思います。知的に言えば、論文を発表できるようなアイデアを具体化したひどい言語を設計するのと同じくらい、プログラマーが気に入るような言語を設計する価値はあります。
1. 大規模なライブラリを整理するには?
ライブラリはプログラミング言語のますます重要なコンポーネントになりつつあります。ライブラリはサイズも大きくなりつつあり、これは危険です。必要な機能を実行するライブラリ関数を見つけるのに、自分で書くよりも時間がかかる場合、そのコードはすべてマニュアルを分厚くするだけです (Symbolics のマニュアルがその好例です)。したがって、ライブラリを整理する方法を検討する必要があると思います。理想的なのは、プログラマーがどのライブラリ呼び出しが正しい動作をするか推測できるようにライブラリを設計することです。
2. 人々は本当にプレフィックス構文を恐れているのでしょうか?
これは、私が何年も考えてきたが、いまだに答えがわからないという意味で、未解決の問題です。プレフィックス構文は、数学を除いて、私には完全に自然に思えます。しかし、Lisp があまり人気がないのは、単に馴染みのない構文を持っているからかもしれません。もしそれが本当なら、それについて何かするべきかどうかは別の問題です。
3. サーバーベースのソフトウェアには何が必要ですか?
今後 20 年間に作成される最もエキサイティングな新しいアプリケーションの多くは、Web ベースのアプリケーション、つまりサーバー上に常駐し、Web ブラウザーを通じてユーザーと対話するプログラムになると思います。このような種類のプログラムを作成するには、いくつかの新しいものが必要になるかもしれません。
必要なことの 1 つは、サーバーベースのアプリがリリースされる新しい方法のサポートです。デスクトップ ソフトウェアのように 1 年に 1 回か 2 回の大きなリリースを行うのではなく、サーバーベースのアプリは小さな変更の連続としてリリースされます。1 日に 5 回から 10 回リリースされることもあります。そして原則として、誰もが常に最新バージョンを使用します。
プログラムをデバッグ可能に設計する方法をご存知ですか? サーバーベースのソフトウェアも同様に変更可能に設計する必要があります。簡単に変更できるか、少なくとも小さな変更と重大な変更を区別できる必要があります。
意外にも、サーバー ベースのソフトウェアに役立つ可能性があるもう 1 つの要素は継続です。Web ベースのソフトウェアでは、継続渡しスタイルのようなものを使用して、Web セッションの本質的に状態のない世界でサブルーチンの効果を得ることができます。コストが高すぎなければ、実際の継続を使用する価値があるかもしれません。
4. 発見すべき新しい抽象化は何か?
これがどれほど合理的な希望かはわかりませんが、個人的に本当にやりたいことの 1 つは、新しい抽象化を発見することです。これは、ファーストクラス関数や再帰、さらにはキーワード パラメータを持つのと同じくらい大きな違いを生むものです。これは実現不可能な夢かもしれません。このようなものはそれほど頻繁に発見されるものではありません。しかし、私は常に探しています。
1. 好きな言語を使用できます。
アプリケーション プログラムを書くということは、かつてはデスクトップ ソフトウェアを書くことを意味していました。そしてデスクトップ ソフトウェアでは、アプリケーションをオペレーティング システムと同じ言語で書く傾向が強くあります。そのため 10 年前は、ソフトウェアを書くということは、C でソフトウェアを書くことをほぼ意味していました。やがて、アプリケーション プログラムは珍しい言語で書いてはいけないという伝統が生まれました。この伝統は長い時間をかけて発展したため、管理者やベンチャー キャピタリストなどの非技術者もそれを学びました。
サーバーベースのソフトウェアは、このモデル全体を吹き飛ばします。サーバーベースのソフトウェアでは、好きな言語を使用できます。まだこれを理解している人はほとんどいません (特にマネージャーやベンチャー キャピタリスト)。少数のハッカーはこれを理解しており、Perl や Python などの新しいインディーズ言語について耳にするのもそのためです。Perl や Python について耳にするのは、人々が Windows アプリの作成に使用しているからではありません。
プログラミング言語の設計に関心を持つ私たちにとって、これが意味することは、私たちの仕事に対して潜在的な実際の聴衆が存在するということです。
2. スピードはプロファイラーから生まれます。
言語設計者、または少なくとも言語実装者は、高速なコードを生成するコンパイラーを記述することを好みます。しかし、これがユーザーにとって言語を高速にする要因だとは思いません。Knuth はずっと以前、速度が問題になるのはいくつかの重大なボトルネックの場合のみであると指摘しました。そして、試したことのある人なら誰でも、これらのボトルネックがどこにあるかを推測することはできないことを知っています。プロファイラーが答えです。
言語設計者は間違った問題を解決しています。ユーザーは高速に実行するためにベンチマークを必要としません。必要なのは、自分のプログラムのどの部分を書き直す必要があるかを示す言語です。実際に速度はそこから生まれます。したがって、言語実装者がコンパイラの最適化に費やす時間の半分を、代わりに優れたプロファイラーの作成に費やせば、最終的に利益が得られるかもしれません。
3. 言語の設計を推進するアプリケーションが必要です。
これは絶対的なルールではないかもしれませんが、最高の言語はすべて、その言語を使って書かれていた何らかのアプリケーションと共に進化してきたようです。C はシステム プログラミングに必要な人々によって書かれました。Lisp は部分的に記号微分を行うために開発されましたが、McCarthy は開発に非常に熱心で、1960 年に Lisp に関する最初の論文を発表した際にも微分プログラムを書いていました。
アプリケーションが何らかの新しい問題を解決する場合は特に効果的です。これにより、プログラマーが必要とする新しい機能を言語に取り入れる傾向が高まります。私は個人的に、サーバーベースのアプリケーションの作成に適した言語を作成することに興味があります。
[パネルディスカッションでは、Guy Steele 氏もこの点を指摘し、使用している言語がコンパイラの作成を目的としていない限り、アプリケーションでその言語用のコンパイラを作成するべきではないという追加の提案をしました。]
4. 言語は使い捨てプログラムを書くのに適している必要があります。
使い捨てプログラムとは、限られたタスクのために素早く書くプログラムのことです。周りを見回せば、多くの大規模で本格的なプログラムが使い捨てプログラムから始まったことに気づくと思います。ほとんどのプログラムが使い捨てプログラムから始まったとしても驚きません。したがって、一般的なソフトウェアの作成に適した言語を作りたいのであれば、使い捨てプログラムの作成に適した言語でなければなりません。なぜなら、ほとんどのソフトウェアはそれが幼生段階だからです。
5. 構文は意味論と関連しています。
構文と意味論は完全に別個のものであると考えるのが一般的です。これは衝撃的に聞こえるかもしれませんが、実際にはそうではないかもしれません。言語に何を求めるかは、それをどのように表現するかに関係しているのではないかと思います。
最近、Robert Morris と話していたのですが、彼は、演算子のオーバーロードは、インフィックス構文の言語の方が有利だと指摘しました。プレフィックス構文の言語では、定義する関数はすべて実質的に演算子です。自分で作った新しいタイプの数値にプラスを定義したい場合、それらを加算する新しい関数を定義するだけで済みます。インフィックス構文の言語でこれを行うと、オーバーロードされた演算子の使用と関数呼び出しの見た目に大きな違いがあります。
1. 新しいプログラミング言語。
1970 年代には、新しいプログラミング言語を設計することが流行していました。最近はそうではありません。しかし、サーバーベースのソフトウェアによって、新しい言語が再び流行すると思います。サーバーベースのソフトウェアでは、好きな言語を使用できます。そのため、誰かが、実際に他の言語よりも優れていると思われる言語を設計した場合、リスクを冒してそれを使用する人が出てくるでしょう。
2. タイムシェアリング。
リチャード・ケルシーは、前回のパネルで、再びその時代が来たというアイデアとしてこれを提示しましたが、私も完全に同感です。私の推測 (そしてマイクロソフトの推測でもあるようですが) は、コンピューティングの多くがデスクトップからリモート サーバーに移行するということです。言い換えれば、タイムシェアリングが復活したということです。そして、言語レベルでのサポートが必要になると思います。たとえば、リチャードとジョナサン・リースは、Scheme 48 内でプロセス スケジューリングを実装する作業に多大な労力を費やしてきたことを私は知っています。
3. 効率性。
最近、ようやくコンピュータが十分に高速になったように思えてきました。バイト コードについて耳にする機会が増え、少なくとも私には、余裕のあるサイクルがあるように感じられます。しかし、サーバー ベースのソフトウェアでは、余裕があるとは思えません。ソフトウェアが実行されるサーバーの費用は誰かが負担する必要があり、マシン 1 台あたりでサポートできるユーザー数が資本コストの割数になります。
したがって、少なくとも計算上のボトルネックにおいては、効率が重要になると思います。サーバーベースのアプリケーションは大量の I/O を実行するため、I/O を高速に実行することが特に重要になります。
結局、バイト コードは勝利をもたらさないかもしれない。Sun と Microsoft は、現在、バイト コードの戦いで対決しているようだ。しかし、彼らがそうしているのは、バイト コードがプロセスに挿入するのに都合が良い場所だからであり、バイト コード自体が良いアイデアだからではない。この戦いの場全体が回避されるかもしれない。それはちょっと面白いだろう。
1. クライアント。
これは単なる推測ですが、ほとんどのアプリケーションで成功するモデルは、純粋にサーバーベースになるだろうと私は推測しています。誰もが自分のクライアントを持つという前提で動作するソフトウェアを設計することは、誰もが正直であるという前提で社会を設計するようなものです。確かに便利ですが、決して実現しないと想定する必要があります。
何らかの形で Web にアクセスできるデバイスが急増すると思いますが、それらについて想定できることは、単純な HTML とフォームをサポートできることだけです。携帯電話にブラウザが搭載されるでしょうか。Palm Pilot に電話機能が搭載されるでしょうか。Blackberry の画面は大きくなりますか。ゲームボーイで Web を閲覧できるようになりますか。時計ではどうでしょうか。わかりません。すべてがサーバー上にあると賭けても、それを知る必要はありません。すべての頭脳がサーバー上にある方がはるかに堅牢です。
2. オブジェクト指向プログラミング。
これは議論の余地のあることだとは思いますが、オブジェクト指向プログラミングはそれほど大きな問題ではないと思います。ウィンドウ システム、シミュレーション、CAD プログラムなど、特定の種類のデータ構造を必要とする特定の種類のアプリケーションには適したモデルだと思います。しかし、それがすべてのプログラミングのモデルであるべき理由がわかりません。
大企業の人々がオブジェクト指向プログラミングを好む理由の 1 つは、それが仕事のように見えるものを大量に生み出すからだと思います。たとえば、整数のリストとして自然に表現されるものが、今ではあらゆる種類の足場と騒々しさを備えたクラスとして表現できます。
オブジェクト指向プログラミングのもう 1 つの魅力は、メソッドがファーストクラス関数の効果の一部を実現できることです。しかし、これは Lisp プログラマーにとっては古いニュースです。実際のファーストクラス関数があれば、すべてをクラスとメソッドの型に押し込むのではなく、手元のタスクに適した方法でそれらを使用できます。
これが言語設計にとって何を意味するかというと、オブジェクト指向プログラミングをあまり深く組み込むべきではないということだと思います。おそらく答えは、より一般的な基礎的なものを提供して、人々が望むオブジェクト システムをライブラリとして設計できるようにすることです。
3. 委員会による設計。
委員会によって言語を設計することは大きな落とし穴です。誰もが知っている理由だけではありません。委員会はまとまりのない一貫性のない設計を生み出す傾向があることは誰もが知っています。しかし、より大きな危険は彼らがリスクを取らないことだと私は思います。1 人の人が責任者である場合、その人は委員会が決して同意しないリスクを取ることができます。
しかし、良い言語を設計するためにリスクを負う必要があるのでしょうか? 多くの人は、言語設計は従来の常識にかなり忠実に従うべきものであると疑うかもしれません。これは真実ではないと思います。人々が行う他のすべてのことにおいて、報酬はリスクに比例します。言語設計がなぜ異なるべきなのでしょうか?