人気になること
Original2001年5月
(この記事は、ある種のビジネスプランとして書かれたもので、 new languageのためのものです。 そのため、良いプログラミング言語の最も重要な特徴である 非常に強力な抽象化が欠けています。)
私の友人はかつて、著名なオペレーティングシステムの専門家に 本当に良いプログラミング言語を設計したいと話しました。 専門家は、プログラミング言語はその優れた点に基づいて 人気が出たり出なかったりすることはないので、彼の言語が どれほど良くても、誰も使わないだろうと彼に言いました。 少なくとも、それが彼が設計した言語に起こったことです。
言語を人気にする要因は何でしょうか?人気のある 言語はその人気に値するのでしょうか?良いプログラミング言語を 定義することは価値があるのでしょうか?どうやってそれを 行うのでしょうか?
これらの質問への答えは、ハッカーを見て、彼らが何を 求めているかを学ぶことで見つけられると思います。 プログラミング言語はハッカーのためのものであり、 プログラミング言語はハッカーが好きである限り、 プログラミング言語として良いのです(例えば、指示的意味論や コンパイラ設計の演習ではなく)。
1 人気のメカニズム
確かに、ほとんどの人がプログラミング言語をその優れた点に基づいて 選ぶことはないというのは真実です。ほとんどのプログラマーは 誰か他の人から使う言語を指示されます。それでも、私は そのような外部要因がプログラミング言語の人気に与える影響は 時々考えられているほど大きくないと思います。もっと大きな 問題は、ハッカーの良いプログラミング言語の考え方が ほとんどの言語設計者とは異なるということです。
二者の間では、ハッカーの意見が重要です。 プログラミング言語は定理ではありません。人々のために設計された ツールであり、人間の強みと弱みに合わせて設計されなければなりません。 靴が人間の足に合わせて設計されるように。 靴を履いたときに痛いなら、それは悪い靴です。 どれほど彫刻として優雅であっても。
プログラマーの大多数が良い言語と悪い言語を見分けられないかもしれません。 しかし、それは他のツールでも同じです。良い言語を設計することが 無駄な時間であることを意味しません。Expert hackers は良い言語を見ればそれを見分け、使います。専門的なハッカーは 確かに少数派ですが、その少数派が良いソフトウェアをすべて書き、 彼らの影響力は、他のプログラマーが彼らが使う言語を使う傾向があることを意味します。 実際、しばしばそれは単なる影響ではなく命令です。 しばしば、専門的なハッカーは、彼らの上司や教員アドバイザーとして 他のプログラマーにどの言語を使うべきかを指示する人々です。
専門的なハッカーの意見は、プログラミング言語の相対的な人気を決定する 唯一の力ではありません — レガシーソフトウェア(Cobol)や ハイプ(Ada、Java)も役割を果たします — しかし、私はそれが 長期的には最も強力な力であると思います。初期のクリティカルマスと 十分な時間が与えられれば、プログラミング言語はおそらく その人気に見合ったものになります。そして人気は良い言語と悪い言語を さらに分けます。なぜなら、実際のユーザーからのフィードバックは 常に改善につながるからです。どれほど人気のある言語が その生涯の間に変わったかを見てください。PerlやFortranは極端な例ですが、 Lispも多く変わりました。例えば、Lisp 1.5にはマクロがありませんでした。 これらは後に進化し、MITのハッカーがLispを使って実際のプログラムを書くのに 数年を費やした後に登場しました。[1]
したがって、言語が人気になるために良くなければならないかどうかは わかりませんが、言語は良くなるために人気でなければならないと思います。 そして、良くあり続けるためには人気であり続けなければなりません。 プログラミング言語の最先端は静止していません。 それでも、今日のLispは1980年代中頃のMITで持っていたものと ほぼ同じです。なぜなら、それがLispが十分に大きくて要求の厳しい ユーザーベースを持っていた最後の時期だからです。
もちろん、ハッカーは言語を使う前にそれを知っている必要があります。 彼らはどうやってそれを知るのでしょうか?他のハッカーからです。 しかし、他の人がその言語について聞くためには、最初のハッカーのグループが その言語を使っている必要があります。このグループはどれくらいの大きさでなければならないのでしょうか? クリティカルマスを作るためには何人のユーザーが必要でしょうか? 私の直感では、20人だと思います。 もし言語に20人の別々のユーザーがいたら、つまり自分で使うことを決めた 20人のユーザーがいたら、それは本物だと考えます。
そこに到達するのは簡単ではないでしょう。ゼロから20に到達するのが 20から1000に到達するよりも難しいのではないかと思います。 最初の20人のユーザーを得る最良の方法は、おそらくトロイの木馬を使うことです。 つまり、人々が欲しいアプリケーションを提供し、それが新しい言語で書かれているということです。
2 外部要因
プログラミング言語の人気に影響を与える外部要因の一つを認めることから始めましょう。 人気になるためには、プログラミング言語は人気のあるシステムのスクリプト言語でなければなりません。 FortranとCobolは初期のIBMメインフレームのスクリプト言語でした。 CはUnixのスクリプト言語であり、後にPerlもそうでした。 TclはTkのスクリプト言語です。JavaとJavascriptは ウェブブラウザのスクリプト言語として意図されています。
Lispは、非常に人気のあるシステムのスクリプト言語ではないため、 大規模に人気のある言語ではありません。彼が保持している人気は 1960年代と1970年代にさかのぼります。その時、LispはMITの スクリプト言語でした。当時の多くの優れたプログラマーは 何らかの形でMITに関連していました。そして1970年代初頭、 Cの前に、MITのLispの方言であるMacLispは 真剣なハッカーが使いたい唯一のプログラミング言語の一つでした。
今日、LispはEmacsとAutocadという2つの中程度に人気のある システムのスクリプト言語であり、そのため、今日行われている LispプログラミングのほとんどはEmacs LispまたはAutoLispで行われていると 疑っています。
プログラミング言語は孤立して存在しません。ハッキングは 他動詞です — ハッカーは通常何かをハッキングしています — そして実際には、言語はそれがハッキングに使われるものに対して 相対的に評価されます。したがって、人気のある言語を設計したいのであれば、 言語以上のものを提供するか、既存のシステムのスクリプト言語を 置き換えるように設計する必要があります。
Common Lispは人気がないのは、部分的には孤児だからです。 元々はハッキングするためのシステム、Lispマシンと共に 登場しました。しかし、Lispマシン(および並列コンピュータ)は 1980年代に一般目的プロセッサの力の増大によって 押しつぶされました。Common LispはUnixのための良いスクリプト言語であれば 人気を保っていたかもしれません。残念ながら、それは非常に悪いものです。
この状況を説明する一つの方法は、言語がその独自の優れた点で 評価されないと言うことです。別の見方は、プログラミング言語は 何かのスクリプト言語でない限り、本当にプログラミング言語ではないということです。 これは驚きでなければ不公平に思えるだけです。プログラミング言語に 実装があることを期待するのと同じくらい不公平ではないと思います。 それはプログラミング言語の一部です。
プログラミング言語は良い実装を必要とし、これは無料でなければなりません。 企業はソフトウェアにお金を払いますが、個々のハッカーは払わず、 必要なのはハッカーを引き付けることです。
言語にはそれについての本も必要です。本は薄く、よく書かれ、 良い例がたくさん含まれているべきです。K&Rが理想です。 現時点では、言語にはO'Reillyから出版された本が必要だと言っても 過言ではありません。それがハッカーにとって重要であることの テストになりつつあります。
オンラインドキュメントも必要です。実際、本はオンラインドキュメントから 始めることができます。しかし、物理的な本が時代遅れだとは思いません。 その形式は便利であり、出版社によって課せられる事実上の検閲は 有用でありながら不完全なフィルターです。書店は新しい言語について 学ぶための最も重要な場所の一つです。
3 簡潔さ
言語が必要とする3つのもの — 無料の実装、本、ハッキングするもの — を提供できるとしたら、ハッカーが好む言語をどうやって作りますか?
ハッカーが好む一つのことは簡潔さです。ハッカーは怠惰であり、 数学者やモダニスト建築家が怠惰であるのと同じです:彼らは 余分なものを嫌います。プログラムを書く前のハッカーは、 少なくとも無意識的に、どれだけの文字を入力しなければならないかに基づいて どの言語を使うかを決定します。これがハッカーの考え方でないとしても、 言語設計者はそれを前提に行動するのが良いでしょう。
長ったらしい表現でユーザーを甘やかそうとするのは間違いです。 Cobolはこの欠陥で悪名高いです。ハッカーは
add x to y giving z
を書くように求められることを、
z = x+y
を書くことの知性への侮辱と神への罪の間の何かと考えます。
Lispは、プログラムを読みやすくするためにfirstとrestを使うべきだと 言われることがあります。最初の数時間はそうかもしれません。 しかし、ハッカーはcarがリストの最初の要素を意味し、cdrが残りを意味することを すぐに学ぶことができます。firstとrestを使うと、50%多くのタイピングが必要です。 また、異なる長さであるため、carとcdrがしばしばそうであるように、 引数が呼び出されるときに整列しません。コードがページ上でどのように整列するかは 非常に重要です。可変幅フォントで設定されたLispコードをほとんど読めず、 友人たちも他の言語でも同じことが真実だと言っています。
簡潔さは、強く型付けされた言語が劣る一つの場所です。 他のすべてのことが等しい場合、誰もプログラムの最初に 一連の宣言を書くことを望みません。暗黙的にできることは すべて暗黙的であるべきです。
個々のトークンも短くするべきです。PerlとCommon Lispは この問題に関して対極に位置しています。Perlプログラムは ほとんど暗号的に密度が高くなることができますが、 Common Lispの組み込み演算子の名前は滑稽に長いです。 Common Lispの設計者は、おそらくユーザーがこれらの長い名前を 入力するためのテキストエディタを持っていることを期待していました。 しかし、長い名前のコストは、単にそれを入力するコストだけではありません。 それを読むコストや、画面上で占めるスペースのコストもあります。
4 ハッキング可能性
ハッカーにとって簡潔さよりも重要なことがあります。それは 自分が望むことをする能力です。プログラミング言語の歴史の中で、 プログラマーが不適切と見なされることを防ぐために 驚くほど多くの努力がなされてきました。これは危険なほど 思い上がった計画です。言語設計者は、プログラマーが 何を必要とするかを知ることができるのでしょうか? 私は、言語設計者は、彼らが予想しなかったことを 必要とする天才をターゲットユーザーとして考える方が良いと思います。 彼らは自分自身から守られる必要がある不器用な人ではありません。 不器用な人は結局自分の足を撃つでしょう。彼を他のパッケージの 変数を参照することから救うかもしれませんが、間違った問題を解決するために 悪く設計されたプログラムを書くことからは救えず、それに永遠にかかるでしょう。
良いプログラマーはしばしば危険で好ましくないことを したいと思います。好ましくないとは、言語が提示しようとしている 意味的な外観の背後にあることを意味します。例えば、ある高レベルの 抽象の内部表現を取得することです。ハッカーはハッキングを好み、 ハッキングは物事の内部に入り込み、元の設計者を 二度考えさせることを意味します。
自分が二度考えられることを許可してください。 どんなツールを作っても、 人々はあなたが意図した方法とは異なる方法でそれを使用します。 これは特にプログラミング言語のような高度に明確化されたツールに当てはまります。 多くのハッカーは、あなたが想像もしなかった方法で あなたの意味モデルを調整したいと思うでしょう。私は、彼らにそれを許可し、 プログラマーにランタイムシステム(ガーベジコレクタなど)を危険にさらすことなく できるだけ多くの内部情報へのアクセスを与えるべきだと言います。
Common Lispでは、私はしばしば構造体のフィールドを反復処理したいと 思います — 例えば、削除されたオブジェクトへの参照を取り除くためや、 初期化されていないフィールドを見つけるためです。私は構造体が 内部で単なるベクトルであることを知っています。それでも、私は 任意の構造体に対して呼び出すことができる汎用関数を書くことができません。 私は名前でフィールドにしかアクセスできません。なぜなら、それが 構造体が意味することだからです。
ハッカーは大きなプログラムの中で一度か二度だけ 意図されたモデルを覆したいと思うかもしれません。しかし、それができることは 大きな違いを生みます。そして、それは単に問題を解決することの 問題以上のことかもしれません。ここには喜びの一種もあります。 ハッカーは、粗雑な内部を探る外科医の秘密の喜びや、 ニキビを潰すティーンエイジャーの秘密の喜びを共有しています。[2] 少なくとも男の子にとって、特定の種類の恐怖は魅力的です。 Maxim誌は、ピンナップと恐ろしい事故の写真を混ぜた 年次の写真集を出版しています。彼らは自分たちの聴衆を知っています。
歴史的に、Lispはハッカーが自由に使えるようにするのが得意でした。 Common Lispの政治的正しさは異常です。初期のLispは すべてに手を出すことを許可しました。その精神の多くは 幸運にもマクロに保存されています。ソースコードに対して 任意の変換を行うことができるのは素晴らしいことです。
クラシックマクロは本物のハッカーのツールです — シンプルで強力で危険です。 彼らが何をするかを理解するのは非常に簡単です:マクロの引数に 関数を呼び出し、返されたものがマクロ呼び出しの代わりに挿入されます。 衛生的マクロは逆の原則を体現しています。彼らはあなたが 何をしているのかを理解することからあなたを守ろうとします。 私は衛生的マクロが一文で説明されるのを聞いたことがありません。 そして、彼らはプログラマーが何を望むことができるかを決定することの危険性の 古典的な例です。衛生的マクロは、他のことの中でも 変数のキャプチャから私を守ることを意図していますが、変数のキャプチャは 私がいくつかのマクロで望むものです。
本当に良い言語は、クリーンでありながら汚れているべきです: クリーンに設計され、よく理解され、高度に直交する演算子の小さなコアを持ち、 しかしハッカーが自由に使えるように汚れているべきです。Cはこのようです。 初期のLispもそうでした。本物のハッカーの言語は常に 少し不良の性格を持っています。
良いプログラミング言語は、「ソフトウェア工学」というフレーズを使う人々が 不満を抱くような特徴を持っているべきです。連続体の反対側には AdaやPascalのような、教えるには良いがそれ以上のものではない 適切さのモデルがあります。
5 使い捨てプログラム
ハッカーに魅力的であるためには、言語は彼らが書きたい プログラムの種類を書くのに適していなければなりません。 そして、それは驚くべきことに、使い捨てプログラムを書くのに 適している必要があります。
使い捨てプログラムとは、限られたタスクのために迅速に書かれるプログラムです: システム管理タスクを自動化するプログラムや、シミュレーションのための テストデータを生成するプログラム、またはデータをある形式から別の形式に 変換するプログラムです。使い捨てプログラムの驚くべきことは、 第二次世界大戦中に多くのアメリカの大学で建設された「一時的な」建物のように、 しばしば捨てられないことです。多くは実際のプログラムに進化し、 実際の機能と実際のユーザーを持つようになります。
私は、最良の大規模プログラムはこのようにして始まるという 直感があります。最初から大きく設計されるのではなく、 フーバーダムのように。何か大きなものをゼロから構築するのは 恐ろしいことです。人々が大きすぎるプロジェクトを引き受けると、 圧倒されてしまいます。プロジェクトは停滞するか、結果は 無味乾燥で木製のものになります:本物のダウンタウンではなく ショッピングモール、ブラジリアではなくローマ、AdaではなくCです。
大きなプログラムを得る別の方法は、使い捨てプログラムから始めて それを改善し続けることです。このアプローチは あまり威圧的ではなく、プログラムの設計は進化から利益を得ます。 もし調べれば、ほとんどの大規模プログラムがこのように開発されたことが わかると思います。そして、このように進化したプログラムは おそらく最初に書かれた言語で書かれ続けるでしょう。 プログラムが移植されることは政治的理由を除いては稀です。 したがって、逆説的に言えば、大規模システムに使用される言語を作りたいのであれば、 使い捨てプログラムを書くのに適している必要があります。なぜなら、 それが大規模システムの出発点だからです。
Perlはこのアイデアの際立った例です。使い捨てプログラムを書くために 設計されただけでなく、ほぼ使い捨てプログラム自体でした。 Perlは報告書を生成するためのユーティリティのコレクションとして 始まり、使い捨てプログラムが大きくなるにつれて プログラミング言語に進化しました。Perl 5(その時点で)まで 言語は真剣なプログラムを書くのに適していませんでしたが、 それでもすでに非常に人気がありました。
使い捨てプログラムに適した言語は何でしょうか?まず第一に、 それは簡単に入手できる必要があります。使い捨てプログラムは 1時間で書くことを期待するものです。したがって、言語は 使用しているコンピュータにすでにインストールされている必要があります。 使用する前にインストールしなければならないものであってはなりません。 そこに存在しなければなりません。Cはオペレーティングシステムに 付属していたので存在しました。Perlは元々システム管理者のための ツールであったため、あなたのものにはすでにインストールされていました。
存在することは、インストールされていること以上の意味があります。 コマンドラインインターフェースを持つインタラクティブな言語は、 別々にコンパイルして実行しなければならない言語よりも より利用可能です。人気のあるプログラミング言語はインタラクティブであり、 迅速に起動するべきです。
使い捨てプログラムにおいてもう一つ望ましいことは簡潔さです。 簡潔さは常にハッカーにとって魅力的であり、特に 1時間で仕上げることを期待しているプログラムでは なおさらです。
6 ライブラリ
もちろん、簡潔さの究極は、プログラムがすでに書かれていて 単に呼び出すだけで済むことです。これが、私が考える プログラミング言語のますます重要になる特徴、ライブラリ関数に つながります。Perlは文字列を操作するための大規模なライブラリを 持っているため勝っています。このクラスのライブラリ関数は 使い捨てプログラムにとって特に重要です。これらはしばしば データを変換したり抽出したりするために元々書かれます。 多くのPerlプログラムはおそらく、いくつかのライブラリ呼び出しを 組み合わせたものとして始まります。
私は、今後50年間にプログラミング言語で起こる進歩の多くが ライブラリ関数に関係すると思います。未来のプログラミング言語は コア言語と同じくらい注意深く設計されたライブラリを持つでしょう。 プログラミング言語の設計は、言語を強く型付けするか弱く型付けするか、 オブジェクト指向にするか関数型にするか、その他のことではなく、 素晴らしいライブラリを設計することに関するものになるでしょう。 型システムの設計について考えるのが好きな言語設計者は これに震え上がるかもしれません。まるでアプリケーションを書くようなものです! 残念ながら。言語はプログラマーのためのものであり、ライブラリは プログラマーが必要とするものです。
良いライブラリを設計するのは難しいです。それは単に 多くのコードを書くことではありません。ライブラリが大きくなりすぎると、 必要な関数を見つけるのにかかる時間が、自分でコードを書くのにかかる時間よりも 長くなることがあります。ライブラリは、コア言語と同様に 小さな直交演算子のセットを使用して設計される必要があります。 プログラマーがどのライブラリ呼び出しが何をするかを 推測できるようにするべきです。
ライブラリはCommon Lispが不足している一つの場所です。 文字列を操作するための基本的なライブラリしかなく、 オペレーティングシステムと対話するためのものはほとんどありません。 歴史的な理由から、Common LispはOSが存在しないかのように振る舞おうとします。 そして、OSと対話できないため、Common Lispの組み込み演算子だけを使って 真剣なプログラムを書くことはおそらく不可能です。実装固有のハックを 使用する必要があり、実際にはこれらはあなたが望むすべてを 提供することはありません。ハッカーは、Common Lispが強力な文字列ライブラリと 良いOSサポートを持っていれば、Lispをもっと高く評価するでしょう。
7 構文
Lispの構文、あるいはより正確には構文の欠如を持つ言語が 人気になることはあるでしょうか?この質問に対する答えはわかりません。 私は、構文がLispが現在人気がない主な理由ではないと思います。 Common Lispには、慣れない構文よりも悪い問題があります。 私は、接頭辞構文に慣れているプログラマーを何人か知っていますが、 それでも彼らはデフォルトでPerlを使用します。なぜなら、Perlは 強力な文字列ライブラリを持ち、OSと対話できるからです。
接頭辞表記には2つの可能な問題があります:それが プログラマーにとって慣れないことであり、十分に密度がないことです。 Lispの世界では、最初の問題が本当の問題であるというのが 一般的な見解です。私はそれほど確信がありません。 はい、接頭辞表記は普通のプログラマーをパニックにさせます。 しかし、普通のプログラマーの意見は重要ではないと思います。 言語は専門的なハッカーがそれをどう思うかに基づいて人気が出たり 出なかったりします。専門的なハッカーは接頭辞表記に対処できるかもしれません。 Perlの構文は非常に理解しにくいことがありますが、それが Perlの人気の妨げにはなっていません。むしろ、それがPerlのカルトを 育むのに役立ったかもしれません。
より深刻な問題は、接頭辞表記の拡散性です。専門的なハッカーにとって、 それは本当に問題です。誰もa[x,y]と書けるときに (aref a x y)を書くことを望みません。
この特定のケースでは、問題をうまく解決する方法があります。 データ構造をインデックス上の関数のように扱うと、 (a x y)と書くことができ、これはPerlの形式よりもさらに短いです。 同様のトリックは他のタイプの表現を短くするかもしれません。
インデントを重要にすることで、多くの括弧を取り除く(または オプションにする)ことができます。プログラマーは コードを読むときにそうします:インデントが一つのことを示し、 区切りが別のことを示すとき、私たちはインデントに従います。 インデントを重要視することで、この一般的なバグの原因を排除し、 プログラムを短くすることができます。
時には、接尾辞構文の方が読みやすいことがあります。 これは特に数学的表現に当てはまります。私はプログラミング人生の 全てを通じてLispを使用してきましたが、接頭辞の数学的表現が 自然だとは思いません。それでも、コードを生成する際には 任意の数の引数を取る演算子があると便利です。 したがって、接尾辞構文がある場合は、何らかのリードマクロとして 実装されるべきです。
Lispに構文を導入することに宗教的に反対するべきではないと思います。 それが基礎となるs式に理解しやすい方法で変換される限り。 Lispにはすでにかなりの量の構文があります。誰もがそれを使うことを 強制されない限り、より多くの構文を導入することは必ずしも悪いことではありません。 Common Lispでは、いくつかの区切りが言語のために予約されており、 少なくとも一部の設計者が将来的により多くの構文を持つことを 意図していたことを示唆しています。
Common Lispの中で最もLispらしくない構文の一つは フォーマット文字列にあります。フォーマットは独自の言語であり、 その言語はLispではありません。もしLispにより多くの構文を導入する計画があれば、 フォーマット指定子をそれに含めることができるかもしれません。 マクロが他の種類のコードを生成するのと同じように、 フォーマット指定子を生成できると良いでしょう。
著名なLispハッカーは、彼のCLTLのコピーが フォーマットのセクションに開くことを私に教えてくれました。 私のもそうです。これはおそらく改善の余地があることを示しています。 また、プログラムが多くのI/Oを行うことを意味するかもしれません。
8 効率
良い言語は、誰もが知っているように、速いコードを生成するべきです。 しかし、実際には速いコードは言語の設計で行うことから 主に来るとは思いません。Knuthが長い間前に指摘したように、 速度は特定の重要なボトルネックでのみ重要です。 そして、多くのプログラマーがそれ以来観察しているように、 これらのボトルネックがどこにあるかについては非常にしばしば 間違っています。
したがって、実際には速いコードを得る方法は 非常に良いプロファイラーを持つことであり、例えば 言語を強く型付けすることではありません。プログラム内の すべての呼び出しのすべての引数の型を知る必要はありません。 ボトルネックで引数の型を宣言できる必要があります。 さらに、ボトルネックがどこにあるかを見つけることができる必要があります。
Lispに対する人々の不満の一つは、何が高価かを知るのが難しいことです。 これは真実かもしれません。非常に抽象的な言語を持ちたい場合は 避けられないかもしれません。そして、いずれにせよ、良いプロファイリングが 問題を解決するのに大いに役立つと思います:すぐに何が高価かを学ぶでしょう。
ここでの問題の一部は社会的です。言語設計者は 速いコンパイラを書くのが好きです。それが彼らのスキルを測る方法です。 彼らはプロファイラーをせいぜいアドオンと考えます。 しかし、実際には良いプロファイラーは、速いコードを生成するコンパイラよりも その言語で書かれた実際のプログラムの速度を改善するのに 多くのことをするかもしれません。ここでも、言語設計者は ユーザーと少し乖離しています。彼らは少し間違った問題を解決する 良い仕事をしています。
アクティブなプロファイラーを持つことは良いアイデアかもしれません。 プログラマーがそれを求めるのを待つのではなく、パフォーマンスデータを プログラマーにプッシュするのです。例えば、プログラマーが ソースコードを編集するときに、ボトルネックを赤で表示することができます。 別のアプローチは、実行中のプログラムで何が起こっているかを 何らかの形で表現することです。これは、実行中のプログラムがたくさんある サーバーベースのアプリケーションでは特に大きな利点になります。 アクティブなプロファイラーは、プログラムが実行されているときに メモリで何が起こっているかを視覚的に示したり、何が起こっているかを 知らせる音を出したりすることができます。
音は問題の良い手がかりです。私が働いていたある場所では、 ウェブサーバーで何が起こっているかを示す大きなダイヤルのボードがありました。 針は小さなサーボモーターによって動かされ、回転するときに わずかな音を立てました。私は自分のデスクからそのボードを見ることができませんでしたが、 サーバーに問題があるときに音で即座に判断できることがわかりました。
非効率的なアルゴリズムを自動的に検出するプロファイラーを書くことも 可能かもしれません。特定のメモリアクセスのパターンが 悪いアルゴリズムの確実な兆候であることがわかるかもしれません。 もしコンピュータの中で私たちのプログラムを実行している小さな存在がいたら、 彼はおそらく連邦政府の職員のように長く悲痛な話を持っているでしょう。 私はしばしば、プロセッサを多くの無駄な追跡に送っているような気がしますが、 それが何をしているのかを見る良い方法はありません。
現在、多くのLispはバイトコードにコンパイルされ、次に インタープリターによって実行されます。これは通常、実装を 移植しやすくするために行われますが、これは有用な言語機能になるかもしれません。 バイトコードを言語の公式な一部にし、プログラマーが ボトルネックでインラインバイトコードを使用できるようにすることは 良いアイデアかもしれません。そうすれば、そのような最適化も 移植可能になります。
エンドユーザーが認識する速度の性質は変わりつつあるかもしれません。 サーバーベースのアプリケーションの台頭に伴い、ますます多くのプログラムが I/Oバウンドになるかもしれません。I/Oを速くすることは価値があります。 言語は、シンプルで迅速なフォーマットされた出力関数のような 直接的な手段で助けることができ、キャッシングや永続オブジェクトのような 深い構造的変更でも助けることができます。
ユーザーは応答時間に関心があります。しかし、もう一つの種類の効率が ますます重要になります。それは、プロセッサごとにサポートできる 同時ユーザーの数です。近い将来に書かれる多くの興味深いアプリケーションは サーバーベースであり、サーバーごとのユーザー数は そのようなアプリケーションをホストする人にとって重要な質問です。 サーバーベースのアプリケーションを提供するビジネスの資本コストにおいて、 これは除数です。
何年もの間、効率はほとんどのエンドユーザーアプリケーションでは あまり重要ではありませんでした。開発者は、各ユーザーが デスク上にますます強力なプロセッサを持つと仮定することができました。 そして、パーキンソンの法則によれば、ソフトウェアは利用可能なリソースを 使用するように拡大しました。それはサーバーベースのアプリケーションで 変わります。その世界では、ハードウェアとソフトウェアは 一緒に提供されます。サーバーベースのアプリケーションを提供する企業にとって、 サーバーごとにサポートできるユーザー数は 利益に非常に大きな違いをもたらします。
いくつかのアプリケーションでは、プロセッサが制限要因となり、 実行速度が最も重要な最適化対象になります。 しかし、しばしばメモリが制限となります。各ユーザーのデータに必要な メモリの量によって同時ユーザーの数が決まります。 言語はここでも助けることができます。スレッドの良いサポートは すべてのユーザーが単一のヒープを共有できるようにします。 永続オブジェクトや遅延読み込みのための言語レベルのサポートがあると 助けになるかもしれません。
9 時間
人気のある言語に必要な最後の要素は時間です。誰も 消えてしまうかもしれない言語でプログラムを書くことを望みません。 多くのプログラミング言語がそうであるように。したがって、ほとんどのハッカーは 言語が数年存在してからでないと使用を検討しない傾向があります。
素晴らしい新しいものの発明者はしばしばこれに驚かされますが、 人々にメッセージを伝えるには時間が必要です。私の友人は 誰かに何かを頼まれたとき、最初の一回はほとんど何もしません。 彼は、人々が望まないことを頼むことがあることを知っています。 彼の時間を無駄にしないために、彼は何かを頼まれるのを 3回目か4回目まで待ちます。その時点で、頼んでいる人は かなりイライラしているかもしれませんが、少なくとも彼らは 本当に求めているものを望んでいる可能性が高いです。
ほとんどの人は、新しいことを聞いたときに同様のフィルタリングを 行うことを学びました。彼らは何かを10回聞くまで 注意を払い始めません。彼らは完全に正当化されています: 新しいホットな何かの大多数は時間の無駄であることが判明し、 最終的には消えていきます。VRMLを学ぶのを遅らせたことで、 私はそれを全く学ぶ必要がなくなりました。
したがって、新しいものを発明する人は、人々がそれを理解し始めるまで 何年もメッセージを繰り返し続けることを期待しなければなりません。 私たちは、私の知る限り、最初のウェブサーバーベースの アプリケーションを書きましたが、それがダウンロードする必要がないことを 人々に伝えるのに数年かかりました。彼らが愚かだったわけではありません。 彼らはただ私たちを無視していました。
良いニュースは、単純な繰り返しが問題を解決するということです。 あなたがする必要があるのは、物語を語り続けることであり、 最終的には人々が聞き始めるでしょう。人々があなたがそこにいることに気づくのは 注意を払うときではなく、あなたがまだそこにいることに気づくときです。
勢いを得るのに通常しばらく時間がかかるのは良いことです。 ほとんどの技術は、最初に立ち上げられた後もかなり進化します — 特にプログラミング言語はそうです。新しい技術にとって、数年間 少数の初期採用者だけに使用されることほど良いことはありません。 初期採用者は洗練されており要求が厳しく、あなたの技術に残っている 欠陥をすぐに明らかにします。ユーザーが少ないと、すべてのユーザーと 密接に連絡を取ることができます。そして、初期採用者は システムを改善するときに寛容であり、たとえそれがいくつかの破損を引き起こしても。
新しい技術が導入される方法は2つあります:有機的成長法と ビッグバン法です。有機的成長法は、クラシックな 資金不足のガレージスタートアップの例です。数人の男が 無名の中で新しい技術を開発します。彼らはマーケティングなしで それを立ち上げ、最初は少数の(熱心に献身的な)ユーザーしか持ちません。 彼らは技術を改善し続け、その間にユーザーベースは 口コミで成長します。彼らが気づく前に、彼らは大きくなります。
もう一つのアプローチ、ビッグバン法は、VCの支援を受けた 大規模にマーケティングされたスタートアップの例です。彼らは 製品を急いで開発し、大々的に発表し、すぐに(彼らが望むように) 大規模なユーザーベースを持つことを期待します。
一般的に、ガレージの人々はビッグバンの人々を羨ましく思います。 ビッグバンの人々はスムーズで自信に満ち、VCから尊敬されています。 彼らはすべての最高のものを手に入れることができ、立ち上げに伴うPRキャンペーンは 彼らを有名人にする副次的な効果を持っています。ガレージの成長の人々は 自分たちが貧しく愛されていないと感じます。しかし、私は彼らが 自分たちを哀れむのはしばしば間違っていると思います。 有機的成長はビッグバン法よりも良い技術と豊かな創業者を 生むようです。今日の支配的な技術を見てみると、ほとんどが 有機的に成長したことがわかります。
このパターンは企業だけに当てはまるわけではありません。 スポンサー付きの研究にも見られます。MulticsとCommon Lispは ビッグバンプロジェクトであり、UnixとMacLispは 有機的成長プロジェクトです。
10 再設計
「最良の文章は再執筆である」とE.B.ホワイトは書きました。 すべての良い作家はこれを知っており、ソフトウェアにも当てはまります。 デザインの最も重要な部分は再設計です。プログラミング言語は特に 再設計が十分に行われていません。
良いソフトウェアを書くためには、同時に2つの対立する アイデアを頭に持っておく必要があります。若いハッカーの 自分の能力に対する無邪気な信頼と、同時にベテランの 懐疑心です。あなたは どれほど難しいことがあるのか?を 考えながら、同時に それは決してうまくいかないと 考えることができなければなりません。
この矛盾は実際には存在しないことを認識することが トリックです。あなたは2つの異なることに対して楽観的であり、 懐疑的である必要があります。問題を解決する可能性については 楽観的であるべきですが、これまでの解決策の価値については 懐疑的であるべきです。
良い仕事をする人々は、彼らが取り組んでいるものが 良くないと思うことがよくあります。他の人々は彼らが 成し遂げたことを見て驚嘆しますが、創造者は心配でいっぱいです。 このパターンは偶然ではありません:それは心配が 作品を良くしたのです。
希望と心配をバランスよく保つことができれば、 それらはプロジェクトを前進させるでしょう。あなたの 2つの足が自転車を前に進めるのと同じように。 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言語です。フリッツ・クンツェの公式伝記はLワードに言及することを慎重に避けています。しかし、私の推測では、新しいLispをLispと呼ぶことを恐れる必要はないと思います。Lispは非常に優れたハッカーの間で多くの潜在的な尊敬を持っています — 例えば、6.001を受講し、それを理解した人たちです。そして、それがあなたが勝つ必要のあるユーザーです。
「ハッカーになる方法」で、エリック・レイモンドはLispをラテン語やギリシャ語のようなものとして説明しています — 知的な演習として学ぶべき言語であり、実際には使用しないかもしれません:
Lispは、あなたがそれを最終的に理解したときに得られる深い啓発体験のために学ぶ価値があります。その体験は、たとえあなたがLisp自体をあまり使わなくても、残りの人生でより良いプログラマーにしてくれるでしょう。
もし私がLispを知らなかったら、これを読むことで疑問を持つでしょう。もしそれが何か意味があるのなら、私をより良いプログラマーにする言語は、プログラミングにより良い言語であることを意味します。そして、それが実際にエリックが言っていることの含意です。
その考えがまだ浮かんでいる限り、ハッカーは新しいLispに対して受け入れやすいと思います、たとえそれがLispと呼ばれていても。しかし、このLispは1970年代の古典的なLispのようなハッカーの言語でなければなりません。それは簡潔で、シンプルで、ハッキング可能でなければなりません。そして、ハッカーが今やりたいことをするための強力なライブラリを持っていなければなりません。
ライブラリの問題に関しては、PerlやPythonのような言語に対抗する余地があると思います。今後数年で書かれる必要がある新しいアプリケーションの多くは、サーバーベースのアプリケーションです。新しいLispがPerlと同じくらい良い文字列ライブラリを持たない理由はありませんし、この新しいLispがサーバーベースのアプリケーションのための強力なライブラリも持っていれば、非常に人気が出る可能性があります。本物のハッカーは、いくつかのライブラリ呼び出しで難しい問題を解決できる新しいツールに鼻を鳴らすことはありません。覚えておいてください、ハッカーは怠惰です。
サーバーベースのアプリケーションのためのコア言語サポートを持つことは、さらに大きな勝利になるかもしれません。たとえば、複数のユーザーを持つプログラムや、タイプタグのレベルでのデータ所有権に対する明示的なサポートです。
サーバーベースのアプリケーションは、この新しいLispが何にハッキングされるかという質問への答えも提供します。LispをUnixのスクリプト言語として改善することは悪くないでしょう。(悪化させるのは難しいでしょう。)しかし、既存の言語に対抗する方が簡単な分野があると思います。Tclのモデルに従い、サーバーベースのアプリケーションをサポートする完全なシステムと共にLispを提供する方が良いかもしれません。Lispはサーバーベースのアプリケーションに自然に適しています。レキシカルクロージャは、UIが単なる一連のウェブページであるときにサブルーチンの効果を得る方法を提供します。S式はHTMLにうまくマッピングされ、マクロはそれを生成するのが得意です。サーバーベースのアプリケーションを書くためのより良いツールが必要であり、新しいLispも必要であり、両者は非常にうまく機能するでしょう。
12 夢の言語
要約として、ハッカーの夢の言語を説明してみましょう。夢の言語は美しい、クリーンで簡潔です。すぐに立ち上がるインタラクティブなトップレベルがあります。非常に少ないコードで一般的な問題を解決するプログラムを書くことができます。あなたが書くプログラムのほとんどのコードは、あなたのアプリケーションに特有のコードです。他のすべてはあなたのために行われています。
言語の構文は、欠点があるほど簡潔です。不要な文字を入力する必要はなく、シフトキーを多く使う必要もありません。
大きな抽象を使用することで、プログラムの最初のバージョンを非常に迅速に書くことができます。後で最適化したいときには、注意を集中させるべき場所を教えてくれる非常に良いプロファイラがあります。内側のループを目を見張るほど速くすることができ、必要に応じてインラインバイトコードを書くこともできます。
学ぶための良い例がたくさんあり、言語は直感的であるため、数分で例から使い方を学ぶことができます。マニュアルをあまり見る必要はありません。マニュアルは薄く、警告や条件が少ないです。
言語は小さなコアを持ち、コア言語と同じくらい注意深く設計された強力で高い直交性を持つライブラリがあります。ライブラリはすべてうまく連携しており、言語内のすべてが高級カメラの部品のようにうまく組み合わさっています。何も非推奨になったり、互換性のために保持されたりすることはありません。すべてのライブラリのソースコードは簡単に入手可能です。オペレーティングシステムや他の言語で書かれたアプリケーションと簡単に対話できます。
言語は層で構築されています。高レベルの抽象は、低レベルの抽象から非常に透明な方法で構築されており、必要であればそれを手に入れることができます。
絶対に隠す必要のないものは何も隠されていません。言語は、あなたの作業を節約する方法としてのみ抽象を提供し、あなたに何をすべきかを指示する方法としては提供しません。実際、言語はその設計においてあなたが平等な参加者であることを奨励します。あなたはそれについてのすべてを変更でき、構文さえも含めて、あなたが書くものは、できる限り、事前定義されたものと同じ地位を持っています。
ノート
[1] 現代のアイデアに非常に近いマクロは、1964年にティモシー・ハートによって提案されました。Lisp 1.5がリリースされた2年後のことです。最初に欠けていたのは、変数のキャプチャや複数の評価を回避する方法でした。ハートの例は両方の影響を受けています。
[2] When the Air Hits Your Brainの中で、神経外科医フランク・ヴェルトシックは、彼の主任レジデントであるゲイリーが外科医と内科医(「ノミ」)の違いについて話す会話を語ります:
ゲイリーと私は大きなピザを注文し、空いているブースを見つけました。主任はタバコに火をつけました。「あのクソノミを見てみろ、彼らは一生に一度しか見ない病気についておしゃべりしている。ノミの問題は、彼らは奇妙なものしか好きじゃない。彼らは自分たちの主なケースを嫌っている。それが私たちとクソノミの違いだ。見てみろ、私たちは大きくてジューシーな腰椎椎間板ヘルニアが大好きだけど、彼らは高血圧が嫌いだ....」
腰椎椎間板ヘルニアをジューシーだと考えるのは難しいです(文字通りを除いて)。それでも、彼らが何を意味しているのかは分かると思います。私はしばしば追跡するのが楽しいバグを持っていました。プログラマーでない誰かは、バグに喜びがあるとは想像しにくいでしょう。すべてがうまく機能する方が良いに決まっています。ある意味では、そうです。しかし、特定の種類のバグを追跡することには否定できないほどの厳しい満足感があります。