Loading...

人気になること

Original

May 2001

(この記事は、一種のビジネスプランとして書かれたものです。 新しい言語のために。 そのため、良いプログラミング言語の最も重要な特徴である、非常に強力な抽象化が欠けています(当然のことながら)。)

友人の一人が、かつて著名なオペレーティングシステムの専門家に、本当に良いプログラミング言語を設計したいと話したことがあります。その専門家は、それは時間の無駄だ、プログラミング言語は、そのメリットに基づいて人気が出たり、人気がなくなったりするものではない、そのため、どんなに良い言語であっても、誰も使わないだろう、と言いました。少なくとも、彼が設計した言語はそうでした。

では、何が言語を人気にするのでしょうか?人気のある言語は、その人気に値するのでしょうか?良いプログラミング言語を定義しようとする価値はあるのでしょうか?どのようにすれば良いのでしょうか?

これらの質問への答えは、ハッカーを見て、彼らが何を望んでいるかを学ぶことで見つけることができると私は思います。プログラミング言語は、ハッカーのためのものです。そして、プログラミング言語は、(例えば、意味論的意味論やコンパイラ設計の練習ではなく)プログラミング言語として良いのは、ハッカーがそれを気に入っている場合のみです。

1 人気のメカニズム

確かに、ほとんどの人は、プログラミング言語を単にそのメリットに基づいて選択しているわけではありません。ほとんどのプログラマーは、他の誰かにどの言語を使うか指示されています。しかし、私は、そのような外部要因がプログラミング言語の人気度に与える影響は、一般的に考えられているほど大きくないと思います。より大きな問題は、ハッカーが考える良いプログラミング言語は、ほとんどの言語設計者とは異なるということです。

この2つのうち、ハッカーの意見の方が重要です。プログラミング言語は定理ではありません。それは、人々のために設計されたツールであり、靴が人間の足に合わせて設計されているように、人間の強みと弱みに合わせて設計されなければなりません。靴を履いたときに窮屈なら、それは彫刻作品としてどんなにエレガントであっても、悪い靴です。

ほとんどのプログラマーは、良い言語と悪い言語を見分けることができないのかもしれません。しかし、それは他のどんなツールでも同じです。それは、良い言語を設計しようとするのが時間の無駄だという意味ではありません。熟練したハッカーは、良い言語を見ればわかりますし、それを使いこなします。熟練したハッカーは、確かにごく少数ですが、そのごく少数のハッカーが、すべての良いソフトウェアを書き、その影響力は、他のプログラマーが彼らが使う言語を使う傾向があるほどです。実際、多くの場合、それは単なる影響力ではなく、命令です。熟練したハッカーは、しばしば、上司や学部指導教官として、他のプログラマーにどの言語を使うか指示する人々です。

熟練したハッカーの意見は、プログラミング言語の相対的な人気度を決定する唯一の力ではありません。レガシーソフトウェア(Cobol)や誇大広告(Ada、Java)も役割を果たしますが、私は、それが長期的に最も強力な力であると考えています。初期の臨界質量と十分な時間があれば、プログラミング言語はおそらく、その価値に見合った人気を得るでしょう。そして、人気は、良い言語と悪い言語をさらに分離します。なぜなら、実際のユーザーからのフィードバックは、常に改善につながるからです。人気のある言語が、その寿命の中でどれほど変化してきたかを見てください。PerlとFortranは極端な例ですが、Lispでさえ、大きく変化しています。例えば、Lisp 1.5にはマクロがありませんでした。マクロは、MITのハッカーがLispを使って実際のプログラムを書き始めてから数年後に進化しました。[1]

したがって、言語が人気になるためには良いものでなければならないかどうかは別として、私は、言語が良くなるためには人気になる必要があると思います。そして、良くなり続けるためには、人気を維持する必要があります。プログラミング言語の最先端は、静止していません。しかし、今日私たちが持っているLispは、1980年代半ばのMITで開発されたものとほぼ同じです。なぜなら、それはLispが十分な規模と要求の厳しいユーザーベースを持っていた最後の時期だからです。

もちろん、ハッカーは、言語を使う前に、その言語について知っておく必要があります。彼らはどのようにして知るのでしょうか?他のハッカーから。しかし、他のハッカーがその言語について知るためには、その言語を使う初期のハッカーのグループがなければならないのです。このグループは、どれくらいの規模でなければならないのでしょうか?何人のユーザーが臨界質量を形成するのでしょうか?思いつくままに言えば、20人です。もし、言語が20人の独立したユーザー、つまり、20人のユーザーが独自にその言語を使うことを決めた場合、私はそれを現実のものと考えます。

そこへたどり着くのは簡単ではありません。ゼロから20人になる方が、20人から1000人になるよりも難しいのではないかと私は思います。最初の20人のユーザーを獲得する最良の方法は、おそらくトロイの木馬を使うことです。つまり、新しい言語で書かれた、人々が欲しいアプリケーションを提供することです。

2 外部要因

プログラミング言語の人気度に影響を与える外部要因を1つ認めるところから始めましょう。人気になるためには、プログラミング言語は、人気のあるシステムのスクリプト言語でなければなりません。FortranとCobolは、初期のIBMメインフレームのスクリプト言語でした。CはUnixのスクリプト言語であり、その後、Perlもそうでした。TclはTkのスクリプト言語です。JavaとJavascriptは、Webブラウザのスクリプト言語になることを意図しています。

Lispは、大規模な人気のあるシステムのスクリプト言語ではないため、大規模な人気のある言語ではありません。Lispが保持している人気は、1960年代と1970年代に遡り、その当時、LispはMITのスクリプト言語でした。当時の偉大なプログラマーの多くは、何らかの形でMITに関係していました。そして、1970年代初頭、Cが登場する前に、MITのLisp方言であるMacLispは、真剣なハッカーが使用したいと思う唯一のプログラミング言語の1つでした。

今日、Lispは、EmacsとAutocadという2つのほどほど人気のあるシステムのスクリプト言語であり、そのため、今日行われているLispプログラミングのほとんどは、Emacs LispまたはAutoLispで行われているのではないかと私は思います。

プログラミング言語は、孤立して存在するものではありません。ハックは他動詞です。ハッカーは通常、何かをハックしています。そして、実際には、言語は、ハックするために使われているものに対して相対的に評価されます。そのため、人気のある言語を設計したいのであれば、言語以上のものを提供するか、既存のシステムのスクリプト言語を置き換えるように言語を設計する必要があります。

Common Lispは、孤児であるため、人気がありません。Common Lispは、もともとハックするためのシステム、Lispマシンと共に提供されていました。しかし、Lispマシン(並列コンピュータと共に)は、1980年代に汎用プロセッサの性能向上によって押しつぶされました。Common Lispは、Unixの良いスクリプト言語だったら、人気を維持していたかもしれません。しかし、残念ながら、Common Lispはひどいスクリプト言語です。

この状況を説明する1つの方法は、言語は独自のメリットで評価されるわけではない、ということです。もう1つの見方は、プログラミング言語は、何かしらのスクリプト言語でもある場合にのみ、真のプログラミング言語である、ということです。これは、驚きとして訪れる場合にのみ、不公平に思えるでしょう。私は、それは、プログラミング言語が、例えば、実装を持っていることを期待するのと同じくらい不公平ではないと思います。それは、プログラミング言語の一部です。

もちろん、プログラミング言語には、良い実装が必要です。そして、それは無料である必要があります。企業はソフトウェアにお金を払いますが、個々のハッカーはそうではありません。そして、あなたが惹きつけなければならないのは、ハッカーです。

言語には、その言語に関する本も必要です。その本は、薄くて、よく書かれていて、良い例がたくさん載っている必要があります。K&Rが理想的です。現時点では、言語にはO'Reillyから出版された本がなければならないと言っても過言ではありません。それは、ハッカーにとって重要なことのテストになりつつあります。

オンラインドキュメントも必要です。実際、その本は、オンラインドキュメントとして始めることができます。しかし、私は、物理的な本はまだ時代遅れではないと思います。そのフォーマットは便利であり、出版社によって課せられた事実上の検閲は、不完全ながらも役に立つフィルターです。書店は、新しい言語について学ぶための最も重要な場所の1つです。

3 簡潔さ

言語に必要な3つのもの、つまり、無料の実装、本、そしてハックする何かを提供できたとしましょう。では、ハッカーが気に入るような言語をどのように作るのでしょうか?

ハッカーが好きなものの1つは、簡潔さです。ハッカーは、数学者やモダニストの建築家と同じように、怠け者です。彼らは、余計なものを嫌います。ハッカーがプログラムを書こうとしているときに、少なくとも無意識に、使用する言語を、タイプする必要がある文字の総数に基づいて決めていると言っても、それほど的外れではありません。これがハッカーの正確な考え方ではないとしても、言語設計者は、そうであるかのように行動する方が良いでしょう。

英語に似た長い表現を使って、ユーザーを甘やかそうとするのは間違いです。Cobolはこの欠陥で有名です。ハッカーは、

add x to y giving z

ではなく、

z = x+y

を書くように求められることを、知能に対する侮辱と神の怒りの両方と考えるでしょう。

Lispは、carとcdrではなく、firstとrestを使うべきだ、とよく言われています。なぜなら、そうすればプログラムを読みやすくなるからです。最初の数時間はそうかもしれません。しかし、ハッカーは、carがリストの最初の要素を意味し、cdrが残りを意味することをすぐに学ぶことができます。firstとrestを使うということは、50%多くのタイピングを意味します。また、それらは長さが異なるため、carとcdrのように、連続する行で呼び出されたときに、引数が揃いません。私は、コードがページ上でどのように揃っているかが、非常に重要であることに気づきました。私は、可変幅フォントで設定されたLispコードをほとんど読むことができません。そして、友人は、他の言語でも同じことが言えると言っています。

簡潔さは、強く型付けされた言語が負ける場所の1つです。他のすべてが同じであれば、誰もプログラムを、一連の宣言で始めたいとは思いません。暗黙的にできることは、すべて暗黙的にすべきです。

個々のトークンも短くする必要があります。PerlとCommon Lispは、この点で正反対の立場にあります。Perlプログラムは、ほとんど暗号的に密な場合がありますが、Common Lispの組み込み演算子の名前は、おかしなほど長いです。Common Lispの設計者は、ユーザーがこれらの長い名前をタイプしてくれるテキストエディタを持っていることを期待していたのでしょう。しかし、長い名前のコストは、単にタイプするコストだけではありません。読むコストと、画面に表示されるスペースのコストもあります。

4 ハッカビリティ

ハッカーにとって、簡潔さよりも重要なものがあります。それは、自分のやりたいことができることです。プログラミング言語の歴史の中で、驚くほど多くの努力が、プログラマーが不適切とみなされることを行うのを防ぐために費やされてきました。これは、危険なほど傲慢な計画です。言語設計者は、プログラマーが何をしたいのか、どのようにしてわかるのでしょうか?私は、言語設計者は、自分のターゲットユーザーを、自分が予想もしなかったことをする必要がある天才と考える方が良いと思います。むしろ、自分自身から守られる必要があるお調子者ではなく。お調子者は、いずれにしても足を撃ち抜きます。別のパッケージの変数を参照することから彼を救うことができるかもしれませんが、間違った問題を解決するために、ひどく設計されたプログラムを書いて、それを完成させるのに永遠の時間を費やすことから彼を救うことはできません。

優秀なプログラマーは、しばしば、危険で好ましくないことをしたいと思うものです。好ましくないというのは、言語が提示しようとしている意味上のファサードの背後にあることを意味します。例えば、高レベルの抽象化の内部表現を手に入れることです。ハッカーはハックするのが好きで、ハックとは、物事の中に入り込み、元の設計者を疑うことです。

*自分自身を疑われるようにしましょう。*どんなツールを作っても、人々は意図していない方法でそれを使います。そして、これは、プログラミング言語のような、非常に明確に定義されたツールでは特に当てはまります。多くのハッカーは、あなたが想像もしなかった方法で、あなたの意味論的モデルを調整したいと思うでしょう。私は、彼らにそうさせてください。ガベージコレクターのようなランタイムシステムを危険にさらすことなく、可能な限り多くの内部的なものをプログラマーにアクセスできるようにしてください。

Common Lispでは、私はしばしば、構造体のフィールドを反復処理したいと思っていました。例えば、削除されたオブジェクトへの参照をすべて取り除いたり、初期化されていないフィールドを見つけたりするためです。私は、構造体は、単なるベクトルであることを知っています。しかし、私は、どんな構造体にも呼び出すことができる汎用関数を書くことができません。私は、名前でしかフィールドにアクセスできません。なぜなら、それが構造体が意味するものであるからです。

ハッカーは、大きなプログラムの中で、意図されたモデルを覆すことを、1回か2回しかやりたくないかもしれません。しかし、それができるということは、どれほどの違いを生むのでしょうか?そして、それは、単に問題を解決すること以上の問題かもしれません。そこには、一種の喜びもあります。ハッカーは、外科医が内臓をいじくり回すときの秘密の喜び、そして、十代の若者がニキビを潰すときの秘密の喜びを共有しています。[2] 少なくとも男の子にとっては、ある種の恐怖は魅力的です。Maxim誌は、ピンナップと凄惨な事故の写真を混ぜて、毎年写真集を出版しています。彼らは、自分の読者を知っています。

歴史的に、Lispは、ハッカーが自分のやりたいようにさせてきました。Common Lispの政治的正しさは、異常です。初期のLispは、すべてを手に入れることができました。幸いなことに、その精神の多くは、マクロに保存されています。ソースコードに対して任意の変換を行うことができるなんて、素晴らしいことです。

古典的なマクロは、真のハッカーのツールです。シンプルで、強力で、危険です。マクロが何をしているのかを理解するのは非常に簡単です。マクロの引数に関数を呼び出し、関数が返すものは、マクロ呼び出しの代わりに挿入されます。衛生的なマクロは、反対の原則を体現しています。衛生的なマクロは、マクロが何をしているのかを理解することからあなたを守ろうとします。私は、衛生的なマクロが1文で説明されたのを聞いたことがありません。そして、それは、プログラマーが何を望むことを許されるのかを決めることの危険性の典型的な例です。衛生的なマクロは、変数キャプチャなどから私を守ることを意図していますが、変数キャプチャは、私が一部のマクロでまさに望んでいるものです。

本当に良い言語は、クリーンでダーティなものでなければなりません。クリーンに設計され、よく理解され、高度に直交した演算子の小さなコアを持ち、ハッカーが自由に使えるという意味でダーティです。Cは、そのような言語です。初期のLispもそうでした。真のハッカーの言語は、常に少し悪趣味な性格を持っています。

良いプログラミング言語は、「ソフトウェアエンジニアリング」というフレーズを使うような人々を、首をかしげて不快にさせるような機能を持っているはずです。その反対側に位置するのが、AdaやPascalのような言語です。これらの言語は、礼儀正しさの模範であり、教育には適していますが、それ以外にはあまり役に立ちません。

5 使い捨てプログラム

ハッカーにとって魅力的であるためには、言語は、彼らが書きたい種類のプログラムに適している必要があります。そして、それは、驚くべきことに、使い捨てプログラムを書くのに適している必要があることを意味します。

使い捨てプログラムとは、限られたタスクのために、素早く書くプログラムのことです。例えば、システム管理タスクを自動化したり、シミュレーション用のテストデータを作成したり、データをあるフォーマットから別のフォーマットに変換したりするためのプログラムです。使い捨てプログラムの驚くべき点は、第二次世界大戦中にアメリカの多くの大学で建てられた「仮設」の建物のように、しばしば捨てられないことです。多くの使い捨てプログラムは、実際のプログラムに進化し、実際の機能と実際のユーザーを持つようになります。

私は、最高の大きなプログラムは、最初から大きく設計されたものではなく、フーバーダムのように、この方法で始まっているのではないかと考えています。最初から何か大きなものを構築するのは、恐ろしいことです。人々が大きすぎるプロジェクトを引き受けると、彼らは圧倒されてしまいます。プロジェクトは行き詰まるか、結果は不毛で木のように硬くなります。ショッピングモールではなく、本当のダウンタウン、ブラジリアではなく、ローマ、Adaではなく、Cです。

大きなプログラムを得るもう1つの方法は、使い捨てプログラムから始めて、それを改善し続けることです。このアプローチは、それほど気が滅入るものではなく、プログラムの設計は、進化から恩恵を受けます。私は、もし調べれば、これが、ほとんどの大きなプログラムが開発された方法であることがわかると思います。そして、このように進化したプログラムは、おそらく、最初に書かれた言語で書かれたままです。なぜなら、プログラムが移植されることは、政治的な理由を除いて、まれだからです。そして、逆説的に、大きなシステムに使用される言語を作りたいのであれば、使い捨てプログラムを書くのに適した言語にしなければならないのです。なぜなら、大きなシステムは、そこから生まれるからです。

Perlは、この考え方の顕著な例です。Perlは、使い捨てプログラムを書くために設計されただけでなく、それ自体がほぼ使い捨てプログラムでした。Perlは、レポートを生成するためのユーティリティのコレクションとして始まりました。そして、人々がPerlで書いた使い捨てプログラムが大きくなるにつれて、プログラミング言語に進化していきました。Perl 5(もしそうなら)になるまで、その言語は本格的なプログラムを書くのに適したものではありませんでした。しかし、Perlはすでに、非常に人気がありました。

何が言語を、使い捨てプログラムに適したものにするのでしょうか?まず、それは、すぐに利用できるものでなければなりません。使い捨てプログラムは、1時間で書けることを期待するものです。そのため、その言語はおそらく、あなたが使っているコンピュータにすでにインストールされている必要があります。それは、使う前にインストールする必要があるものであってはなりません。それは、そこに存在しなければなりません。Cは、オペレーティングシステムに付属していたため、そこに存在していました。Perlは、もともとシステム管理者のためのツールであったため、そこに存在していました。そして、あなたのシステム管理者は、すでにそれをインストールしていました。

利用可能であるということは、インストールされているということ以上の意味を持ちます。コマンドラインインターフェースを持つ対話型言語は、コンパイルして別々に実行する必要がある言語よりも、より利用可能です。人気のあるプログラミング言語は、対話型であり、高速に起動する必要があります。

使い捨てプログラムで欲しいもう1つのものは、簡潔さです。簡潔さは、常にハッカーにとって魅力的であり、1時間で完成することを期待するプログラムでは、特にそうです。

6 ライブラリ

もちろん、簡潔さの究極は、プログラムがすでに書かれていて、それを呼び出すだけ、ということです。そして、これは、私が考えるに、プログラミング言語のますます重要な機能になるであろう、ライブラリ関数へとつながります。Perlは、文字列を操作するための大きなライブラリを持っているため、優勢です。このクラスのライブラリ関数は、特に、使い捨てプログラムにとって重要です。使い捨てプログラムは、しばしば、データを変換したり、抽出したりするために書かれます。多くのPerlプログラムは、おそらく、いくつかのライブラリ呼び出しを組み合わせたものとして始まります。

私は、今後50年間でプログラミング言語で起こる進歩の多くは、ライブラリ関数に関係するのではないかと考えています。私は、将来のプログラミング言語は、コア言語と同じように慎重に設計されたライブラリを持つようになると思います。プログラミング言語の設計は、言語を強く型付けするか、弱く型付けするか、オブジェクト指向にするか、関数型にするか、あるいは何か他のものにするかではなく、どのように素晴らしいライブラリを設計するか、ということになるでしょう。型システムの設計について考えたいと思っている言語設計者は、これを見てぞっとするかもしれません。それは、アプリケーションを書くようなものです!残念です。言語はプログラマーのためのものだし、ライブラリはプログラマーが必要とするものです。

良いライブラリを設計するのは難しいです。それは、単にたくさんのコードを書くことではありません。ライブラリが大きくなりすぎると、必要な関数を見つけるのに、自分でコードを書くよりも時間がかかることがあります。ライブラリは、コア言語と同じように、直交した演算子の小さなセットを使って設計する必要があります。プログラマーは、どのライブラリ呼び出しが、自分の必要なことを行うのかを推測できるはずです。

ライブラリは、Common Lispが不足している場所の1つです。文字列を操作するためのライブラリは、ごくわずかしかありません。そして、オペレーティングシステムと通信するためのライブラリは、ほとんどありません。歴史的な理由から、Common Lispは、OSが存在しないふりをしようとしています。そして、OSと通信できないため、Common Lispの組み込み演算子のみを使って、本格的なプログラムを書くことはできません。あなたは、いくつかの実装固有のハックも使う必要があり、実際には、これらのハックは、あなたが望むすべてを提供するわけではありません。ハッカーは、Common Lispが強力な文字列ライブラリと優れたOSサポートを持っていれば、Lispをもっと高く評価するでしょう。

7 構文

Lispの構文、あるいはより正確には、構文の欠如を持つ言語は、人気になることができるのでしょうか?私は、この質問に対する答えはわかりません。私は、構文がLispが現在人気がない主な理由ではないと考えています。Common Lispは、なじみのない構文よりも、もっと深刻な問題を抱えています。私は、前置記法に慣れているにもかかわらず、Perlをデフォルトで使用しているプログラマーを何人か知っています。なぜなら、Perlは強力な文字列ライブラリを持ち、OSと通信できるからです。

前置記法には、2つの可能性のある問題があります。1つは、プログラマーにとってなじみがなく、もう1つは、十分に密ではないということです。Lispの世界では、一般的な見解は、最初の問題が真の問題であるということです。私は、それほど確信していません。確かに、前置記法は、普通のプログラマーをパニックに陥れます。しかし、私は、普通のプログラマーの意見は重要ではないと思います。言語は、熟練したハッカーがどう思うかによって、人気が出たり、人気がなくなったりします。そして、私は、熟練したハッカーは、前置記法に対処できるのではないかと思います。Perlの構文は、かなり理解不能な場合がありますが、それはPerlの人気に邪魔になることはありませんでした。むしろ、それは、Perlカルトを育むのに役立ったのかもしれません。

より深刻な問題は、前置記法の拡散性です。熟練したハッカーにとって、それは本当に問題です。誰も、a[x,y]と書けるのに、(aref a x y)を書きたくはありません。

この特定のケースでは、この問題を回避する方法があります。データ構造を、インデックスに対する関数であるかのように扱うと、(a x y)と書くことができます。これは、Perlの形式よりもさらに短いです。同様のトリックは、他の種類の式を短くすることができます。

インデントを意味のあるものにすることで、多くの括弧を削除したり、オプションにしたりすることができます。プログラマーは、コードをこのように読んでいます。インデントが何かを言っているのに、デリミタが別のことを言っている場合、私たちはインデントに従います。インデントを意味のあるものとして扱うことは、この一般的なバグの原因を排除するだけでなく、プログラムを短くします。

中置記法の方が読みやすい場合もあります。これは、数学式では特に当てはまります。私は、プログラミング人生のすべてをLispを使って過ごしてきましたが、それでも前置記の数学式は自然に感じません。しかし、それは、特にコードを生成する場合、任意の数の引数を取る演算子を持つことは便利です。そのため、中置記法を使用する場合は、おそらく、何らかの読み込みマクロとして実装する必要があります。

私は、Lispに構文を導入することに、宗教的に反対するべきではないと思います。それは、基礎となるS式に、よく理解された方法で変換される限りです。Lispには、すでに多くの構文があります。誰もがそれを強制的に使う必要がない限り、もっと構文を導入しても、必ずしも悪いことではありません。Common Lispでは、一部のデリミタは言語のために予約されており、少なくとも一部の設計者は、将来、より多くの構文を導入することを意図していたことを示唆しています。

Common Lispで最もひどいLispらしさのない構文の1つは、フォーマット文字列にあります。formatは、それ自体が言語であり、その言語はLispではありません。Lispにさらに構文を導入する計画があれば、フォーマット指定子は、その中に含めることができるかもしれません。マクロが、他の種類のコードを生成するのと同じように、フォーマット指定子を生成できるようになれば、良いことです。

著名なLispハッカーは、自分のCLTLは、formatのセクションに開いていると言っていました。私のCLTLもそうです。これは、改善の余地があることを示しているのでしょう。それは、プログラムが多くの入出力を行っていることを意味しているのかもしれません。

8 効率

良い言語は、誰もが知っているように、高速なコードを生成する必要があります。しかし、実際には、高速なコードは、言語の設計であなたがすることから、主に生まれるものではないと思います。クヌースが長い間前に指摘したように、速度は、特定の重要なボトルネックでのみ問題になります。そして、多くのプログラマーがそれ以来観察してきたように、私たちは、これらのボトルネックがどこにあるのか、非常にしばしば間違っています。

そのため、実際には、高速なコードを得る方法は、非常に良いプロファイラを持つことであり、例えば、言語を強く型付けすることではありません。プログラム内のすべての呼び出しのすべての引数の型を知る必要はありません。ボトルネックの引数の型を宣言できる必要があります。そして、さらに重要なことに、ボトルネックがどこにあるのかを調べることができる必要があります。

人々がLispに対して抱いている不満の1つは、何が高価なのかを判断するのが難しいということです。それは本当かもしれません。それは、非常に抽象的な言語を持ちたいのであれば、避けられないことかもしれません。そして、いずれにしても、私は、良いプロファイラがあれば、その問題を解決するのに役立つと思います。すぐに、何が高価なのかがわかるでしょう。

ここでの問題の一部は、社会的です。言語設計者は、高速なコンパイラを書くのが好きです。それが、彼らのスキルを測る方法です。彼らは、プロファイラを、せいぜいアドオンと考えています。しかし、実際には、良いプロファイラは、高速なコードを生成するコンパイラよりも、言語で書かれた実際のプログラムの速度を向上させるのに役立つ可能性があります。ここでも、言語設計者は、ユーザーと少しだけ疎遠になっています。彼らは、少しだけ間違った問題を解決することに、本当に良い仕事をしているのです。

アクティブなプロファイラを持つのは、良い考えかもしれません。つまり、プログラマーが要求するのを待つのではなく、パフォーマンスデータをプログラマーにプッシュすることです。例えば、エディタは、プログラマーがソースコードを編集するときに、ボトルネックを赤で表示することができます。もう1つのアプローチは、実行中のプログラムで何が起こっているのかを、何らかの形で表現することです。これは、実行中のプログラムをたくさん見ることができる、サーバーベースのアプリケーションでは、特に大きな成果になります。アクティブなプロファイラは、プログラムの実行中にメモリで何が起こっているのかを、グラフィカルに表示したり、何が起こっているのかを伝える音を出したりすることもできます。

音は、問題に対する良い合図です。私が働いていたある場所で、私たちは、Webサーバーで何が起こっているのかを示す、大きなダイヤル盤を持っていました。針は、小さなサーボモーターによって動かされており、回転すると、わずかな音がしていました。私は、自分の机からその盤を見ることはできませんでしたが、私は、サーバーに問題が発生すると、その音ですぐにわかることに気づきました。

非効率なアルゴリズムを自動的に検出するプロファイラを書くことも、可能かもしれません。特定のパターンのメモリアクセスが、悪いアルゴリズムの確実な兆候であることが判明するのではないかと、私は思います。もし、コンピュータの内部を走り回って、私たちのプログラムを実行している小さな男がいたら、彼は、連邦政府の職員と同じくらい長く、悲痛な話を、自分の仕事について語るでしょう。私は、しばしば、プロセッサを多くの無駄な探索に送り出しているような気がするのですが、プロセッサが何をしているのかを見る良い方法がありませんでした。

多くのLispは、現在、バイトコードにコンパイルされ、その後、インタプリタによって実行されます。これは、通常、実装を移植しやすくするために実行されますが、それは、役に立つ言語機能になる可能性があります。バイトコードを言語の公式な一部にし、プログラマーがボトルネックにインラインバイトコードを使用できるようにするのは、良い考えかもしれません。そうすれば、そのような最適化も移植可能になります。

エンドユーザーが感じる速度の性質は、変化しているのかもしれません。サーバーベースのアプリケーションの台頭とともに、ますます多くのプログラムが、I/Oバウンドになる可能性があります。I/Oを高速にする価値はあります。言語は、シンプルで高速なフォーマットされた出力関数のような、簡単な対策と、キャッシュや永続的なオブジェクトのような、深い構造的な変更の両方で、役立ちます。

ユーザーは、応答時間に興味を持っています。しかし、もう1つの種類の効率が、ますます重要になってきています。それは、プロセッサあたりにサポートできる同時ユーザーの数です。近い将来に書かれる興味深いアプリケーションの多くは、サーバーベースのものであり、サーバーあたりのユーザー数は、そのようなアプリケーションをホストする人にとって、重要な問題です。サーバーベースのアプリケーションを提供するビジネスの資本コストでは、これが除数になります。

長年、効率は、ほとんどのエンドユーザーアプリケーションでは、それほど重要ではありませんでした。開発者は、各ユーザーが、ますます強力なプロセッサを自分の机の上に置いていると仮定することができました。そして、パーキンソンの法則によって、ソフトウェアは、利用可能なリソースを使うように拡大してきました。それは、サーバーベースのアプリケーションでは、変わるでしょう。その世界では、ハードウェアとソフトウェアは、一緒に提供されます。サーバーベースのアプリケーションを提供する企業にとって、サーバーあたりにサポートできるユーザー数は、収益に大きな影響を与えるでしょう。

一部のアプリケーションでは、プロセッサが制限要因となり、実行速度が最適化する上で最も重要なものになります。しかし、多くの場合、メモリが制限要因になります。同時ユーザーの数は、各ユーザーのデータに必要なメモリの量によって決まります。言語は、ここでも役立ちます。スレッドの優れたサポートにより、すべてのユーザーが、単一のヒープを共有できるようになります。永続的なオブジェクトや、遅延読み込みのための言語レベルのサポートがあることも、役立つかもしれません。

9 時間

人気のある言語に必要な最後の要素は、時間です。誰も、消えてしまう可能性のある言語でプログラムを書きたくはありません。多くのプログラミング言語がそうであるように。そのため、ほとんどのハッカーは、言語が2、3年間存在するまで、その言語を使うことを検討しません。

素晴らしい新発明をした人は、しばしば、このことに気づいて驚きますが、人々にメッセージを伝えるには、時間が必要です。私の友人の一人は、誰かに初めて頼まれたことは、めったにしません。彼は、人々は、自分が本当に欲しがっているものではないものを、時々頼むことを知っています。自分の時間を無駄にしないために、彼は、3回目か4回目に頼まれたときに初めて何かをします。その頃には、頼んでいる人はかなり腹を立てているかもしれませんが、少なくとも、彼らは、頼んでいるものを本当に欲しいのでしょう。

ほとんどの人は、新しいことを聞いたときに、同様のフィルターをかけることを学んでいます。彼らは、何かについて10回聞いたまで、注意を払い始めません。彼らは、完全に正当です。ほとんどのホットな新製品は、時間の無駄であることが判明し、最終的には消えていきます。VRMLを学ぶのを遅らせたことで、私は、VRMLを学ぶ必要がなくなりました。

そのため、何か新しいものを発明した人は、人々がそれを理解し始めるまで、何年もメッセージを繰り返し続けることを期待しなければなりません。私たちは、知る限り、最初のWebサーバーベースのアプリケーションを書きましたが、人々に、それはダウンロードする必要がないことを理解させるのに、何年もかかりました。彼らは、愚かだったわけではありません。彼らは、私たちを無視していただけです。

良いニュースは、単純な繰り返しによって、その問題は解決されるということです。あなたがする必要があるのは、あなたの話を繰り返し続けることです。そして、最終的に、人々はそれを聞き始めるでしょう。人々があなたの存在に気づいたときに、彼らは注意を払うのではなく、あなたの存在がまだ続いていることに気づいたときに、彼らは注意を払うのです。

勢いを増すまでに時間がかかるのは、当然のことです。ほとんどのテクノロジーは、最初に発売された後も、大きく進化します。特に、プログラミング言語はそうです。新しいテクノロジーにとって、少数の初期採用者だけが、数年間にわたってそれを使用することは、これ以上ないことです。初期採用者は、洗練されていて、要求が厳しく、あなたのテクノロジーに残っている欠陥をすぐに洗い出します。ユーザーが少なければ、すべてのユーザーと密接に連絡を取ることができます。そして、初期採用者は、あなたがシステムを改善するとき、たとえそれがいくつかの破壊を引き起こすとしても、寛容です。

新しいテクノロジーが導入されるには、2つの方法があります。有機的な成長方法と、ビッグバン方法です。有機的な成長方法は、古典的な、資金不足のガレージスタートアップによって例示されています。2人の男が、人知れず、新しいテクノロジーを開発します。彼らは、マーケティングなしでそれを発売し、最初は、少数の(熱心な)ユーザーしかいません。彼らは、テクノロジーの改善を続け、その間、ユーザーベースは口コミで広がります。気がつけば、彼らは大きくなっています。

もう1つのアプローチであるビッグバン方法は、VCの支援を受けた、大々的に宣伝されたスタートアップによって例示されています。彼らは、製品を急いで開発し、大きな宣伝でそれを発売し、すぐに(彼らは望んでいます)、大規模なユーザーベースを獲得します。

一般的に、ガレージの男たちは、ビッグバンの男たちを羨んでいます。ビッグバンの男たちは、スムーズで自信に満ち溢れ、VCから尊敬されています。彼らは、すべての中で最高のものを買う余裕があり、発売に伴うPRキャンペーンは、彼らを有名人にします。有機的な成長の男たちは、自分のガレージに座って、貧しく、愛されていないと感じています。しかし、私は、彼らが自分自身を哀れむのは、しばしば間違いであると思います。有機的な成長は、ビッグバン方法よりも、より良いテクノロジーと、より裕福な創業者を生み出すようです。今日の支配的なテクノロジーを見ると、ほとんどが有機的に成長したものであることがわかります。

このパターンは、企業にのみ適用されるわけではありません。あなたは、それが、スポンサー付きの研究でも見られます。MulticsとCommon Lispは、ビッグバンプロジェクトであり、UnixとMacLispは、有機的な成長プロジェクトでした。

10 再設計

「最高の文章は、書き直しである」とE. B. ホワイトは書いています。すべての優れた作家は、このことを知っています。そして、それはソフトウェアにも当てはまります。設計の最も重要な部分は、再設計です。特に、プログラミング言語は、十分に再設計されていません。

良いソフトウェアを書くためには、2つの相反するアイデアを同時に頭に入れておく必要があります。あなたは、若いハッカーの、自分の能力に対するナイーブな信念と、同時に、ベテランの懐疑心を持つ必要があります。あなたは、どれほど難しいのでしょうか?と、脳の片方で考えながら、それは決してうまくいかないでしょうと、もう片方の脳で考えることができる必要があります。

コツは、そこに本当の矛盾はないことに気づくことです。あなたは、2つの異なるものについて、楽観的であり、懐疑的である必要があります。あなたは、問題を解決できる可能性について楽観的である必要がありますが、あなたがこれまで得てきた解決策の価値については、懐疑的である必要があります。

良い仕事をする人は、しばしば、自分がやっていることは良くないと考えています。他の人は、彼らの仕事を見て、驚嘆しますが、創造主は、心配でいっぱいです。このパターンは、偶然ではありません。それは、心配が、その仕事を良くしたのです。

希望と心配をバランスよく保つことができれば、それらは、自転車の2本の足が自転車を前に進めるように、プロジェクトを前に進めるでしょう。2サイクルのイノベーションエンジンの最初の段階では、あなたは、問題を解決できるとの自信に突き動かされて、ある問題に熱心に取り組みます。2番目の段階では、あなたは、朝の冷めた目で、自分がやったことを見て、その欠陥をすべて非常に明確に認識します。しかし、あなたの批判的な精神が、あなたの希望を上回らない限り、あなたは、確かに不完全な

ここでは、インターフェースが垂直ではなく水平になるようにシステムを設計することが、ひとつの解決策となるかもしれません。つまり、モジュールが常に垂直に積み重ねられた抽象化の層になるように設計することです。そうすれば、インターフェースは、そのうちのいずれかのモジュールによって所有される傾向を持つでしょう。2つのレベルのうち、下位のレベルは、上位のレベルが書かれている言語になるか、または上位のレベルの奴隷になるかのいずれかです。前者の場合、下位のレベルがインターフェースを所有し、後者の場合、インターフェースは上位のレベルによって決定されます。

11 Lisp

これらのことから、新しいLispへの希望が見えてきます。Lispを含む、ハッカーが求めるものを提供する言語には、希望があります。ハッカーはLispの奇妙さに辟易していると考えていたのは、間違いだったのかもしれません。この安心できる幻想は、Lisp、あるいは少なくともCommon Lispの真の問題、つまりハッカーがやりたいことを実行するのに適していないという問題を見えなくさせていたのかもしれません。ハッカー向けの言語には、強力なライブラリとハッキングする対象が必要です。Common Lispにはどちらもありません。ハッカー向けの言語は簡潔でハッキングしやすいものです。Common Lispはそうではありません。

良いニュースは、Lispそのものがダメなのではなく、Common Lispがダメだということです。もし、ハッカー向けの真の言語となる新しいLispを開発できれば、ハッカーはそれを利用するでしょう。彼らは、仕事をする言語なら何でも利用するでしょう。私たちがすべきことは、この新しいLispが、他の言語よりも重要な仕事をうまくこなせるようにすることだけです。

歴史は、いくつかの励みを与えてくれます。時が経つにつれて、新しいプログラミング言語は、Lispからますます多くの機能を取り入れてきました。あなたが作った言語がLispになるまでには、もはやコピーするものはほとんど残っていません。最新の流行言語であるPythonは、インフィックス構文とマクロのない、薄めたLispです。新しいLispは、この進歩の自然なステップとなるでしょう。

私は時々、それをPythonの改良版と呼ぶのが良いマーケティング戦略になるのではないかと考えています。Lispよりも流行しているように聞こえます。多くの人にとって、Lispは、たくさんの括弧を持つ、遅いAI言語です。Fritz Kunzeの公式バイオグラフィーでは、Lという単語を避けています。しかし、私の推測では、新しいLispをLispと呼ぶことを恐れるべきではありません。Lispは、特に6.001を受講して理解したような、最高のハッカーたちの間では、依然として潜在的な尊敬を集めています。そして、彼らはあなたが獲得する必要があるユーザーです。

「ハッカーになる方法」の中で、Eric Raymondは、Lispをラテン語やギリシャ語のようなもの、つまり実際に使うことはなくても、知的訓練として学ぶべき言語として説明しています。

Lispは、あなたがそれを理解したときに得られる深い啓蒙体験のために学ぶ価値があります。その体験は、あなたが実際にLisp自体を頻繁に使うことはなくても、残りの人生でより良いプログラマーになるようにしてくれるでしょう。

もし私がLispを知っていなければ、この文章を読んだときに疑問を持つでしょう。より良いプログラマーにしてくれる言語とは、もしそれが何か意味を持つのであれば、プログラミングに適した言語を意味します。そして、それは実際にはEricが言っていることの含みです。

その考えがまだ存在している限り、私はハッカーは新しいLispを受け入れるだろうと考えています。たとえそれがLispと呼ばれていてもです。しかし、このLispは、1970年代の古典的なLispのように、ハッカー向けの言語でなければなりません。簡潔で、シンプルで、ハッキングしやすいものでなければなりません。そして、ハッカーが今やりたいことを実行するための強力なライブラリを備えていなければなりません。

ライブラリに関しては、PerlやPythonのような言語を凌駕する余地があると考えています。今後数年で書かれる必要のある新しいアプリケーションの多くは、サーバーベースのアプリケーションになるでしょう。新しいLispがPerlと同じくらい優れた文字列ライブラリを持つ理由はありません。そして、この新しいLispがサーバーベースのアプリケーションのための強力なライブラリも持っていれば、非常に人気が出る可能性があります。真のハッカーは、いくつかのライブラリ呼び出しで難しい問題を解決できる新しいツールを鼻であしらうことはありません。ハッカーは怠け者であることを忘れないでください。

サーバーベースのアプリケーションのためのコア言語のサポートがあれば、さらに大きな勝利となるでしょう。たとえば、複数のユーザーを持つプログラムの明示的なサポート、または型タグレベルでのデータ所有権などです。

サーバーベースのアプリケーションは、この新しいLispで何をハッキングするかという問題に対する答えも与えてくれます。LispをUnixのスクリプト言語としてより良くすることは、決して悪いことではありません。(それを悪くすることは難しいでしょう。)しかし、既存の言語よりも簡単に凌駕できる分野があると考えています。Tclのモデルに従い、Lispをサーバーベースのアプリケーションをサポートするための完全なシステムとともに提供する方が良いかもしれません。Lispは、サーバーベースのアプリケーションに自然に適しています。字句的クロージャは、UIが単なる一連のウェブページの場合に、サブルーチンと同じ効果を得る方法を提供します。S式はHTMLにうまくマッピングされ、マクロはHTMLを生成するのに適しています。サーバーベースのアプリケーションを作成するためのより良いツールが必要であり、新しいLispが必要であり、この2つは非常にうまく連携するでしょう。

12 夢の言語

要約として、ハッカーの夢の言語を説明してみましょう。夢の言語は、美しい、クリーンで、簡潔です。高速に起動する対話型のトップレベルがあります。非常に少ないコードで、一般的な問題を解決するプログラムを書くことができます。あなたが書くプログラムのほとんどのコードは、あなたのアプリケーションに固有のコードです。その他はすべて、あなたのためにすでに完了しています。

言語の構文は、極端に簡潔です。不要な文字を入力する必要はなく、シフトキーを使う必要もほとんどありません。

大きな抽象化を使用することで、プログラムの最初のバージョンを非常に迅速に作成できます。後で最適化したい場合は、本当に優れたプロファイラがあり、どこに注意を集中すべきかを教えてくれます。必要であれば、インラインバイトコードを書くことさえできます。

学ぶための良い例がたくさんあり、言語は直感的なので、数分で例から使い方を学ぶことができます。マニュアルをあまり見る必要はありません。マニュアルは薄く、警告や注釈もほとんどありません。

言語は、小さく、強力で、高度に直交したライブラリを持ち、ライブラリはコア言語と同じように慎重に設計されています。ライブラリはすべてうまく連携し、言語内のすべてが、高級カメラのパーツのように互いにフィットしています。非推奨になったものや、互換性のために残されたものはありません。すべてのライブラリのソースコードは、簡単に利用できます。オペレーティングシステムや他の言語で書かれたアプリケーションとの通信も簡単です。

言語は、層状に構築されています。上位レベルの抽象化は、非常に透明な方法で、下位レベルの抽象化から構築されており、必要であれば、下位レベルの抽象化にアクセスできます。

絶対に必要なものを除いて、何も隠されていません。言語は、あなたに何をすべきかを伝えるのではなく、あなたを助ける方法として、抽象化を提供します。実際、言語は、あなたが言語の設計に平等な参加者になることを奨励しています。構文を含む、言語のすべてを変更することができ、あなたが書いたものは、可能な限り、事前に定義されているものと同じステータスを持ちます。

注記

[1] 現代的なアイデアに近いマクロは、Lisp 1.5がリリースされてから2年後の1964年に、Timothy Hartによって提案されました。当初、欠けていたのは、変数キャプチャと複数評価を回避する方法でした。Hartの例は、どちらも対象となっています。

[2] 脳に空気が当たるときの中で、神経外科医のFrank Vertosickは、彼のチーフレジデントであるGaryが、外科医と内科医(「ノミ」)の違いについて話す会話について語っています。

Garyと私は大きなピザを注文し、空いているブースを見つけました。チーフはタバコに火をつけました。「あのクソノミを見てくれ、一生に一度しか見ないような病気について、おしゃべりしているんだ。ノミの困ったところは、奇妙なものしか好きじゃないんだ。彼らは、自分の日々の仕事は嫌うんだ。それが、私たちとあのクソノミの違いなんだ。見てくれ、私たちは大きなジューシーな腰椎椎間板ヘルニアが大好きだが、彼らは高血圧は嫌いなんだ……」

腰椎椎間板ヘルニアをジューシーだと思うのは難しい(文字通りを除いて)。しかし、私は彼らが何を意味するのか理解していると思います。私はしばしば、ジューシーなバグを追跡してきました。プログラマーではない人は、バグに喜びを見出すことができるという想像をするのは難しいでしょう。すべてがうまくいけば、それは確かに良いことです。ある意味では、それは正しいことです。しかし、特定の種類のバグを追い詰めることに、否定できないほどの暗い満足感があることは確かです。