ポール・グレアム「Lispはどこが違うのか」をコピペ+翻訳しました。




原題は「What Made Lisp Different」で、原文は以下です。


http://www.paulgraham.com/diff.html




「What Made Lisp Different」は、大幅に加筆されて「Revenge of the Nerds」となっています。


ですので「技術野郎の復讐 --Revenge of the Nerds--」とカブるところが非常に多くあります。




この翻訳は川合史朗氏の許可を得て「技術野郎の復讐」から大部分をコピペさせていただいております。


http://www.shiro.dreamhost.com/scheme/trans/icad-j.html


快諾いただきありがとうございました。




またshiro様(=川合史朗氏)、ttamo様、matsOS様の協力をいただいております。ありがとうございます。




Lispはどこが違うのか




2001年12月(rev. 2002年5月)


December 2001 (rev. May 2002)




(このエッセイは、LL1メーリング・リストに対するいくつかの質問の答えだ。現在は「技術野郎の復讐」に組み入れられている)




マッカーシーが1950年代後半に設計した当時、LispはFortranを筆頭とする既存言語との根本的な決別を意味した。




Lispは9つの新しい考えを具体化した:




















































































































































































































































1. 条件式。条件式とは if-then-else という構造だ。今ではあって当然のものだ。それらはLispの開発中にマッカーシーによって発明された。(当時のFortranには、ハードウェアの分岐命令に緊密に結びついた条件付きのgotoしかなかった) Algolの委員会にいたマッカーシーはAlgolに条件式を導入し、それは他の多くの言語に広まった。


2. 関数型。Lispでは関数は整数や文字列と同じようなデータ型のひとつだ。リテラル表記を持ち、変数に代入できて、引数として渡せる、というようなことだ。


3. 再帰。もちろん再帰はLisp以前にも数学的な概念として存在した。しかしLispは再帰をサポートした最初のプログラミング言語だった。(関数をfirst class objectにすることで、再帰は自動的にサポートされるとも言えるかもしれない)


4. 変数の新しい概念。Lispでは全ての変数は実質的にポインタだ。変数ではなく値の方が型を持っており、変数の代入または束縛はポインタの参照先ではなく、ポインタ自体のコピーを意味する。


5. ガベージコレクション。


6. 式でプログラムが構成されること。Lispプログラムは式の木であり、それぞれの式が値を返す(一部のLispでは式が複数の値を返すことができる)。これはFortranとそれに続く多くの言語とは対照的だ。それらの言語は式と文を区別している。


Fortran Iにおいて式と文を区別することは自然だった(入力がパンチカードだった言語では驚くことではない)。文はネストできなかったからだ。数式が使えるようにするのに式は必要だったが、それ以外の処理が値を返す必要も無かった。文の戻り値を受けるものなんて無かったからだ。


この制限はブロック構造化言語の到来によって無くなるはずだったが、その時には既に手遅れだったのだ。式と文の区別は慣行の中に根を下ろしてしまっていた。それはFortranからAlgolに広がり、その子孫の言語へと受け継がれて行った。


言語が完全に式でできているなら、式を好きに構成できる。(Arcの文法を使えば)どちらでもOKだ。


(if foo (= x 1) (= x 2))


or


(= x (if foo 1 2))


7. シンボル型。シンボルは、ポインタ比較によって等価性を判定できるという点で文字列と異なっている


8. シンボルと定数の木によってコードを表現すること。


9. 言語の全てが常に利用可能なこと。読み込み時、コンパイル時、実行時が明確に分離したステップになっていない。読み込み時にコンパイルしてコードを走らせることもできるし、コンパイル時にコードを読んだり走らせたりすることもできるし、実行時にコードを読んだりコンパイルしたりすることができる。


読み込み時にコードを走らせることにより、ユーザがLispの構文を変更することができる。コンパイル時にコードを走らせるというのはマクロの基本だ。実行時にコンパイルするというのはLispをEmacsのようなプログラムの拡張言語として使うことを容易にする。そして、実行時に読み込みができるというのは、プログラム同士がS式を使って通信できるということだ。最後のアイディアは最近XMLとして再発明された。




















































































































































































































































こうしたアイディアはすべて、Lispが発明された当初のプログラミング慣行とはあまりにかけ離れていた。当時のプログラミングは1950年代後半の(貧弱な)ハードウェアによって大きく制限されていたのだ。


主流言語は、人気のある言語で次々と置きかえられながらLispへ向かって進化してきた。1~5までのアイディアはいまや広く取入れられている。6番は主流の言語に現れ始めている。Pythonは7に相当するものを持っているが、そのための構文は無いようだ。8番(と9番)はLispでマクロを可能にし、そしてLispをいまだにユニークにしているものだ。それは(a)あの括弧か、もしくは同じくらいおっかないものを必要とし、そして(b)マクロという最後の力を加えたら、それは新しい言語ではなくLispの新しい方言になってしまうからだろう。(^o^)


他の言語が思いつきで取り入れた方便との比較をLispの説明に使うのは、たとえ現代のプログラマが理解しやすいとしても、おかしなことだ。それは恐らくマッカーシーの考え方とは違う。Lispの目的はFortranの誤りを修正することではなかった。それは計算をわかりやすくしようとしていたら予期せずに生み出されたものだったのだ。