平均を上回る
Original2001年4月、2003年4月改訂
(この記事は2001年のFranz開発者シンポジウムで行った講演に基づいています。)
1995年の夏、私の友人ロバート・モリスと私はViawebというスタートアップを立ち上げました。私たちの計画は、エンドユーザーがオンラインストアを構築できるソフトウェアを書くことでした。当時、このソフトウェアの新しい点は、通常のWebページをインターフェースとして使い、私たちのサーバー上で動作することでした。
もちろん、同じようなアイデアを持っている人がいたかもしれません。しかし、私の知る限り、Viawebは最初のWebベースのアプリケーションでした。私たちにとってそれは非常に新しいアイデアだったので、ソフトウェアがWebを介して動作するということでViawebと名付けました。
このソフトウェアのもう一つの特徴は、主にLispというプログラミング言語で書かれていたことです。Lispを使った大規模なエンドユーザーアプリケーションの1つでした。それまでLispはほとんど大学や研究所で使われていただけでした。[1]
秘密の武器
エリック・レイモンドは「ハッカーになるには」という論文の中で、目指すハッカーが学ぶべき言語について述べています。彼は初心者向けにPythonとJavaを推奨しています。本格的なハッカーはさらにCを学び、Unixをハックし、Perlでシステム管理やCGIスクリプトを書くべきだと提案しています。そして最終的に、真剣なハッカーはLispを学ぶべきだと言っています。
Lispを学ぶことで、ついに理解できるようになったときの深い啓示の経験をすることができます。その経験は、Lispをあまり使わなくても、その後のプログラミングに役立つはずです。
これは、ラテン語を学ぶ理由と同じ議論です。ラテン語を使って仕事を得ることはできませんが、あなたの頭を良くし、英語のような使いたい言語の書き手としての能力を高めてくれます。
しかし、この比喩にはそこまで当てはまりません。ラテン語が仕事に役立たないのは、誰も話さないからです。ラテン語で書いても、誰も理解できません。しかし、Lispはコンピューター言語であり、プログラマーであるあなたが指示したとおりにコンピューターが話します。
では、Lispがプログラマーをより良くするのであれば、なぜ使わないのでしょうか? 絵描きに、彼の絵を良くする筆が与えられたら、その筆を使わないはずがありません。ここでエリック・レイモンドを批判しているわけではありません。全体としては、彼のアドバイスは良いものです。Lispについての彼の意見は、一般的な常識と同じです。しかし、常識には矛盾があります。Lispはプログラマーをより良くするが、使われない。
なぜでしょうか? プログラミング言語はただのツールに過ぎません。Lispが本当によりよいプログラムを生み出すのであれば、使うべきです。そうでなければ、Lispは必要ありません。
これは単なる理論的な問題ではありません。ソフトウェアは非常に競争の激しい業界で、自然な寡占状態に陥りやすいです。ソフトウェアをより早く、より良く書くことができる企業は、他の条件が同じであれば、競合他社を倒すことができます。スタートアップを立ち上げるときは、この点を非常に強く感じます。スタートアップは、すべてか無かになることが多いのです。成功すれば金持ちになれますが、失敗すれば何も得られません。スタートアップでは、間違った技術に賭けると、競合他社に押し潰されてしまいます。
ロバートと私はどちらもLispを良く知っており、Lispを信頼して使うことに疑問を感じませんでした。他の企業がC++やPerlでソフトウェアを書いていることは知っていましたが、それは何も意味しないと分かっていました。そのような方法で技術を選んでいたら、Windowsを使っていることになります。技術を選ぶときは、他の人が何をしているかを無視し、最も効果的なものを検討する必要があります。
これはスタートアップでは特に重要です。大企業であれば、他の大企業と同じことをすることができます。しかし、スタートアップはそうはいきません。スタートアップも他のスタートアップと同じことをしてはいけません。私はこの点を、スタートアップの中でも多くの人が理解していないと思います。
平均的な大企業の成長率は年10%ほどです。つまり、大企業の平均的な方法で事業を行えば、平均的な大企業と同じくらいの成長、つまり年10%ほどの成長が期待できます。
スタートアップでも同じことが言えます。平均的なスタートアップの方法で事業を行えば、平均的な成績が期待できます。問題は、平均的な成績では倒産してしまうということです。スタートアップの生存率は50%を大きく下回ります。したがって、スタートアップを経営する場合は、何か特別なことをしなければなりません。そうでなければ、危険な状況に陥ります。
1995年当時、私たちは競合他社が理解していないことを知っていました。そして今でも多くの人が理解していないことがあります。自社のサーバー上で動作するソフトウェアを書く場合、使う言語は自由に選べるのです。デスクトップソフトウェアを書く場合は、オペレーティングシステムと同じ言語を使うことが強く推奨されます。10年前は、C言語でアプリケーションを書くのが一般的でした。しかし、Webベースのソフトウェアの場合、言語とオペレーティングシステムのソースコードを持っていれば、好きな言語を使えます。
この新しい自由は両刃の剣です。使える言語が増えたことで、どの言語を使うかを考える必要があります。状況の変化を無視しようとする企業は、競合他社に取り残される危険性があります。
使える言語が増えた以上、どの言語を使うべきでしょうか? 私たちはLispを選びました。迅速な開発が重要だと感じたからです。私たち全員が一から始めていたので、新機能を競合他社より早く実装できる企業が大きな優位性を持つはずでした。Lispは素早いソフトウェア開発に適していることを知っていました。しかも、サーバーベースのアプリケーションであれば、開発が完了した瞬間にリリースできるので、迅速な開発の効果が倍増します。
他の企業がLispを使いたがらなかったとしても、それはむしろ良いことだった。 それにより、私たちに技術的な優位性が生まれ、私たちにはそれが必要だった。 Viaweb を立ち上げた時、私たちには事業経験がまったくなかった。 マーケティングや人材採用、資金調達、顧客獲得について何も知らなかった。 私たち二人とも、いわゆる本格的な仕事をしたことがなかった。 唯一できたことは、ソフトウェアを書くことだった。 それが私たちを救ってくれると期待していた。 ソフトウェア部門で得られるあらゆる優位性を手に入れようと考えた。
つまり、Lispを使うことは一種の実験だったと言えるだろう。 私たちの仮説は、Lispでソフトウェアを書けば、競合他社よりも早くさまざまな機能を実装でき、 また、競合他社にはできないようなことも行えるだろうということだった。 そしてLispは非常に高水準な言語なので、大規模な開発チームを必要としないため、 コストを抑えられるはずだった。 もしそうなれば、より良い製品をより安価に提供しつつ、利益を上げられるはずだ。 そうすれば、すべてのユーザーを獲得し、競合他社は廃業に追い込まれるだろう。 少なくともそうなることを期待していた。
この実験の結果はどうだったか? 意外なことに、うまくいった。 最終的には20社から30社ほどの競合他社が現れたが、 彼らのソフトウェアは私たちのものに太刀打ちできなかった。 私たちには、サーバー上で動作しながらもデスクトップアプリケーションのような感覚を ユーザーに与えるWYSIWYGのオンラインストア構築ツールがあった。 一方、競合他社はCGIスクリプトしか持っていなかった。 そして私たちは常に競合他社に先行して機能を追加していった。 時には競合他社が必死に新機能を追加しようとしたこともあったが、 Lispのおかげで、そうした新機能を1、2日で複製してしまうことができた。 プレスリリースが出る前に、私たちもその新機能を持っていることが多かった。
私たちの競合他社にとっては、まるで秘密兵器でも持っているかのように見えたに違いない。 エニグマの暗号を解読しているのではないかと思われたかもしれない。 実際、私たちは秘密兵器を持っていたが、それは彼らが想像していたよりずっと単純なものだった。 競合他社の機能情報が私たちに漏れ出ているわけではなかった。 私たちはただ、誰もが考えられないほど早くソフトウェアを開発できていただけなのだ。
私が9歳のころ、フレデリック・フォーサイスの『ジャッカルの日』という本を手に入れた。 主人公は暗殺者で、フランス大統領を暗殺するよう雇われる。 暗殺者は警察の目をかいくぐり、大統領の経路を見渡せる部屋に入り込む。 杖をついた老人の姿に変装して、警察に全く疑われることなく通り過ぎていく。
私たちの秘密兵器もそれに似ていた。 私たちはAI言語のLispで、奇妙な文法に満ちた括弧だらけのソフトウェアを書いていた。 長年、Lispがそのように表現されるのが私を煩わせていたが、今となっては私たちの 利点になっていた。ビジネスでは、競合他社に理解されない技術的優位性ほど 価値のあるものはない。ビジネスでは、戦争と同じく、驚きは力に匹敵する。
そのため、私は Viaweb 時代、Lispについて公に何も言わないようにしていた。 プレスにも触れず、ウェブサイトでもたまたま私のプロフィールに載っていた 2冊の本のタイトルくらいしか、Lispについて言及していなかった。 これは偶然ではなかった。スタートアップは競合他社に情報を与えるべきではない。 私たちのソフトウェアが何語で書かれているか、あるいは関心がないなら、 それを知られないようにしておきたかったのだ。
私たちの技術を一番よく理解していたのは顧客たちだった。 Viawebがどの言語で書かれているかなど、彼らは気にしていなかった。 ただ、それがとてもよく機能することに気づいていた。 数分でオンラインストアを立ち上げられるようになっていたのだ。 そして主に口コミで、ユーザー数が増えていった。 1996年末には約70のストアがオンラインにあり、1997年末には500、 Yahoo に買収された6か月後には1070ユーザーになっていた。 現在もYahoo Storeとして市場を支配し続けており、Yahooの中でも 最も収益性の高い部門の1つとなっている。 Yahooを1999年に離れたので、今のユーザー数は正確にはわからないが、 最後に聞いた情報では約20,000人だったと記憶している。
Blubパラドックス
Lispはなぜすばらしいのか? そして、Lispがすばらしいのなら、 なぜみんなが使わないのか? これらは修辞的な質問のように聞こえるが、 実は簡単な答えがある。Lispがすばらしいのは、ただ単に最も強力な プログラミング言語だからにほかならない。そして、みんなが使わないのは、 プログラミング言語が単なる技術だけでなく、考え方の習慣でもあり、 それが最も変化しにくいものだからだ。 もちろん、これらの答えにはさらに説明が必要だ。
まず、非常に物議を醸す主張から始めよう。 プログラミング言語には力量の差がある。
少なくとも、高水準言語がマシン語より強力であることは誰もが認めるだろう。 今日の多くのプログラマーは、マシン語で直接プログラミングするのは 望ましくないと考えている。代わりに高水準言語でプログラミングし、 コンパイラにマシン語に翻訳させるべきだと考えている。 この考え方は、ハードウェアにも組み込まれている。1980年代以降、 命令セットはプログラマではなくコンパイラ向けに設計されるようになった。
誰もが、プログラム全体をマシン語で手書きするのは間違いだと知っている。 しかし、より一般的な原則として理解されていないのは、 複数の言語から選べる場合、すべての条件が同じなら、 必ず最も強力な言語を使うべきだということだ。
このルールには多くの例外があります。特定の言語で書かれたプログラムと非常に密接に連携する必要があるプログラムを書く場合は、新しいプログラムを同じ言語で書くのが良いアイデアかもしれません。単純な数値計算やビット操作のようなごく単純なことしかする必要のないプログラムを書く場合は、少し高速かもしれない抽象度の低い言語を使うのが適切かもしれません。そして、短期的に使い捨てのプログラムを書く場合は、その作業に最適なライブラリ関数を持つ言語を使うのが最善かもしれません。しかし、一般的にアプリケーションソフトウェアを書く場合は、可能な限り強力な(合理的に効率的な)言語を使うべきであり、それ以外の言語を使うのは、機械語で書くのと同じ種類の、ただし程度が小さい間違いです。
機械語がきわめて低レベルであることがわかります。しかし、ある種の社会的な慣習として、高水準言語はしばしば同等のものとして扱われています。そうではありません。技術的には「高水準言語」という用語には明確な意味はありません。機械語の一方と、すべての高水準言語の他方との間に明確な境界線はありません。言語は抽象度の連続体 [4] に沿って並んでおり、最も強力なものから機械語まで変化しています。
COBOLを考えてみましょう。COBOLは高水準言語ですが、機械語にコンパイルされます。COBOLがPythonと同等の力を持っていると真剣に主張する人がいるでしょうか。COBOLは機械語に近いと言えるでしょう。
あるいはPerl 4はどうでしょうか。Perl 4とPerl 5の間では、レキシカルクロージャーが言語に追加されました。ほとんどのPerlハッカーは、Perl 5の方がPerl 4よりも強力だと同意するでしょう。しかし、一旦それを認めてしまえば、1つの高水準言語が別の高水準言語よりも強力であることを認めたことになります。そして、特別な場合を除いて、可能な限り最も強力な言語を使うべきだと不可避的に導かれます。
この考え方は、しかし、ほとんど最終的な結論に至っていません。一定の年齢に達すると、プログラマーは自発的に言語を切り替えることはほとんどありません。人々が慣れ親しんでいる言語は、ちょうど良いと考えられがちです。
プログラマーは自分の好きな言語に非常に執着しており、誰かの気持ちを傷つけたくないので、この点を説明するために、仮想の言語「Blub」を使うことにします。Blubは抽象度の連続体の真ん中に位置します。最も強力な言語ではありませんが、COBOLや機械語よりも強力です。
そして実際、私たちの仮想のBlubプログラマーは、それらのどちらも使いません。もちろん、機械語でプログラミングするわけがありません。それがコンパイラの役割です。COBOLについても、誰がそれで何かをやっているのか分からないと思っています。Blubの機能 (x) さえ持っていません。
私たちの仮想のBlubプログラマーが抽象度の連続体を下方向に見ている限り、下を向いていることがわかります。Blubよりも力の弱い言語は明らかに弱いのは、彼が慣れ親しんでいる機能が欠けているからです。しかし、Blubプログラマーが逆方向、つまり上方向を見ると、上を向いていることに気づきません。彼が見るのは単に奇妙な言語に過ぎません。それらは多分Blubと同等の力を持っていると考えていますが、さらに複雑な機能が付加されているだけです。Blubは彼にとって十分良いのは、彼がBlubの考え方に慣れ親しんでいるからです。
一方、より強力な言語を使うプログラマーの視点に立つと、彼はBlubを見下しています。Blubでどうやって何かをやるのか。Blubには y さえ存在しません。
帰納的に、さまざまな言語の力の違いをすべて理解できるプログラマーは、最も強力な言語を理解しているプログラマーだけです。(これは多分エリック・レイモンドが「Lispはあなたをより良いプログラマーにする」と言ったことの意味だと思います。) 他のプログラマーの意見は信頼できません。なぜなら、Blubのパラドックスにより、彼らは自分が使っている言語に満足しているからです。それが彼らのプログラムに関する考え方を決めているからです。
私自身の経験から、これを知っています。高校生のころ、Basicでプログラムを書いていました。その言語には再帰さえサポートされていませんでした。再帰を使わずにプログラムを書くのは想像しにくいですが、当時は再帰を必要としていないと思っていました。私はBasicの考え方をしていました。そして、Basicのマスターでした。
エリック・レイモンドがハッカーに推奨する5つの言語は、抽象度の連続体上のさまざまな位置にあります。それらがお互いに相対的にどこに位置するかは、デリケートな話題です。私が言えるのは、Lispが最上位にあると思うということです。そしてこの主張を支持するために、他の4つの言語に欠けていると感じるものの1つについて話します。マクロなしでどうやって何かをやるのか、と思います。[5]
多くの言語にはマクロと呼ばれるものがあります。しかし、Lispのマクロは独特です。そして信じられないかもしれませんが、それらが行うことはカッコと関係があります。Lispの設計者たちは、Lispのコードにあるすべてのカッコを単に違いを出すためだけに入れたのではありません。Blubプログラマーにとっては、Lispのコードは奇妙に見えます。しかし、それらのカッコには理由があるのです。それらは、Lispと他の言語の根本的な違いの外見的な証拠なのです。
Lispのコードは、Lispのデータオブジェクトで構成されています。そして、ソースファイルに文字が含まれ、文字列がその言語でサポートされているデータ型の1つであるという単純な意味だけではありません。Lispのコードは、パーサによって読み込まれた後は、プログラムが移動できるデータ構造で構成されています。
コンパイラの動作を理解していれば、Lispが奇妙な構文を持っているのではなく、Lispに構文がないのだと理解できます。他の言語でパースされるときに生成されるパーストリーの中にプログラムを書いているのです。しかし、これらのパーストリーは完全にプログラムからアクセス可能です。プログラムでそれらを操作することができます。Lispでは、これらのプログラムをマクロと呼びます。プログラムを書くプログラムなのです。
プログラムがプログラムを書くとは?そんなことをする必要があるのでしょうか? Cobolで考えれば、そうそうないでしょう。Lispで考えれば、いつでもそうです。ここで強力なマクロの例を示して、「これがそうだ!」と言えたらいいのですが、Lispを知らない人にはただの謎としか見えないでしょう。ここで全てを説明する余地はありません。
Ansi Common Lispでは、できるだけ早く進めようと試みましたが、それでもマクロには160ページ目まで到達できませんでした。
しかし、説得力のある議論ができるかもしれません。Viaweb エディタのソースコードの20-25%はマクロでした。マクロは通常のLisp関数よりも書くのが難しく、必要以上に使うのは良くないとされています。つまり、このコードに含まれるマクロはすべて必要不可欠なものなのです。これは、このプログラムの少なくとも20-25%が、他の言語では簡単にはできないことをしていることを意味します。BlubプログラマーがLispの神秘的な力について私の主張に懐疑的であっても、これは彼を好奇心をそそるはずです。私たちはこのコードを自分たちの楽しみのために書いたわけではありません。私たちは小さなスタートアップで、競争相手との差をつけるために必死にプログラミングしていたのです。
疑い深い人なら、ここに何か関連性があるのではないかと考え始めるかもしれません。私たちのコードの大部分は、他の言語ではとても難しいことをしていました。その結果、競争相手のソフトウェアではできないことができるソフトウェアができあがりました。ここには何か関係があるのかもしれません。この糸を辿ってみてください。杖をついて歩く老人にはもっと深いものがあるかもしれません。
スタートアップのための合気道
しかし、Lispを学んでもらうことを期待しているわけではありません(25歳以上の人)。この記事の目的は誰かの考えを変えることではなく、Lispの強力な言語であることを知りつつ、広く使われていないことを心配している人々を安心させることです。競争の場では、それが有利になります。Lispの力は、競争相手がそれを理解していないことで倍増するのです。
スタートアップでLispを使うことを考えるなら、広く使われていないことを心配する必要はありません。むしろ、そのままでいてほしいと願うべきです。そうなる可能性も高いでしょう。プログラミング言語は、ほとんどの人を現在使っているものに満足させる性質があるからです。コンピューターハードウェアの変化は個人の習慣よりはるかに速いため、プログラミングの実践は通常プロセッサの10〜20年遅れています。MITのような場所では1960年代初期から高水準言語でプログラムを書いていましたが、多くの企業は1980年代まで機械語でコードを書き続けていました。多くの人が機械語を書き続けていたのは、プロセッサがリスク命令セットに切り替わるまでだったと思います。
通常、技術は急速に変化します。しかし、プログラミング言語は違います。プログラミング言語は単なる技術ではなく、プログラマーが考えるものでもあります。技術と宗教の半分ずつなのです[6]。そのため、中央値の言語、つまり中央的なプログラマーが使う言語は、氷山のように遅々として動きます。Lispが1960年ごろに導入したガベージコレクションは、今では広く良いものと考えられるようになりました。動的型付けも同様に、人気が高まっています。Lispが1970年代初期に導入したレキシカルクロージャーも、ようやくレーダー画面に登場し始めました。Lispが1960年代半ばに導入したマクロは、未だ未知の領域のままです。
中央値の言語には確かに大きな慣性があります。この強力な力に抗うことはできません。私が提案しているのは、まさにその逆です。合気道の実践者のように、それを自分の味方に付けることです。
大企業で働いている場合、これは簡単ではないかもしれません。Lispを使ってものを作らせてもらうのは、上司が新聞で別の言語がアダのように20年後に世界を制するだろうと読んだ後では、説得するのが難しいでしょう。しかし、まだ上司のいないスタートアップで働いている場合は、私たちがしたように、Blubのパラドックスを自分の有利に使うことができます。競争相手が固定観念に縛られている言語では到底マッチできない技術を使うのです。
もしスタートアップで働くことになったら、競争相手を評価する便利なヒントがあります。求人広告を読むことです。ウェブサイトの他の部分は株式写真や同じような文章かもしれませんが、求人広告は適切な候補者を集めるために具体的でなければなりません。
Viaweb で働いていた年月の間、私は多くの求人広告を読みました。新しい競争相手が毎月のように現れるようでした。最初にすることは、オンラインデモがあるかどうかを確認し、次に求人広告を見ることでした。数年経って、どの企業を気をつけるべきか、どこは心配する必要がないかがわかるようになりました。求人広告にITの雰囲気が強いほど、その企業は危険ではありませんでした。一番安全なのはOracleの経験を求めているところでした。C++やJavaの開発者を求めているところも心配する必要はありませんでした。PerlやPythonのプログラマーを求めているところは少し怖いかもしれません。技術的な側面が本物のハッカーによって運営されているようです。Lispのハッカーを求める求人広告を見たら、本当に心配しなければならないでしょう。
注釈
[1] Viawebは当初2つの部分から成っていました。Lispで書かれたエディタ部分で、ユーザーがサイトを構築し、C言語で書かれた注文システム部分で注文を処理していました。最初のバージョンはほとんどがLispでしたが、注文システムが小さかったためです。後に、C言語で書かれた画像生成モジュールと、主にPerlで書かれた管理モジュールを2つ追加しました。
2003年1月、Yahooは新しいエディターのバージョンをリリースしました。これはC++とPerlで書かれています。しかし、このプログラムがもはやLispで書かれていないかどうかは言うのは難しいです。なぜなら、このプログラムをC++に翻訳するためには、文字通りLispインタープリターを書く必要があったからです。ページ生成テンプレートのソースファイルは、私の知る限り、依然としてLispコードです。(Greenspunの第10の法則を参照)。
[2] ロバート・モリスは、私たちの競合他社がLispを使っていることを知っていたとしても、それを理解することはできなかっただろうと言っています。「もしそれほど賢かったら、すでにLispでプログラミングしているはずだ」。
[3] すべての言語は、チューリング同値の意味では等しく強力ですが、プログラマーが気にかけているのはそうではありません。(誰もチューリングマシンをプログラムしたくありません)。プログラマーが気にかけている種類の力は、正式に定義できないかもしれませんが、それは、より強力な言語の機能を、より弱い言語で実装しなければならないということを意味しているかもしれません。言語Aに文字列からスペースを削除する演算子があり、言語Bにはない場合、それはAがBよりも強力だということにはならないかもしれません。なぜなら、Bでサブルーチンを書けば同じことができるからです。しかし、AがRecursionをサポートし、Bがサポートしていない場合、それは単にライブラリ関数を書いて解決できるようなものではありません。
[4] 注:ネード向け:あるいは上に向かって狭まる格子、形状は問題ではありません。ここで重要なのは、少なくとも部分順序があるということです。
[5] マクロを別の機能として扱うのは少し誤解を招くかもしれません。実際には、その有用性は、レキシカルクロージャやレストパラメーターなどの他のLisp機能によって大幅に高まります。
[6] その結果、プログラミング言語の比較は、宗教戦争の形をとるか、あまりにも中立的で人類学的な大学教科書の形をとります。平和を重んじる人や、テニュアを得たい人は、この話題を避けます。しかし、この問題は半分だけ宗教的なものです。新しい言語を設計したい場合は、特にそこに研究する価値があるものがあります。