Loading...

LISPが他と異なっていた理由

Original

2001年12月 (2002年5月改訂)

(このアーティクルはLL1メーリングリストでの質問に応えて書かれたものです。現在はRevenge of the Nerdsに組み込まれています。)

McCarthyがLispを1950年代後期に設計したとき、それは既存の言語、特にFortranとは大きく異なる革新的なものでした。

Lispには以下の9つの新しいアイデアが体現されていました:

1. 条件分岐 条件分岐は、if-then-elseの構造です。今日では当然のように使われていますが、これはMcCarthyがLispを開発する過程で発明したものです。(当時のFortranには条件付きのgotoしかなく、それは基礎となるハードウェアの分岐命令に基づいていました。)McCarthyはAlgolの委員会にいたため、条件分岐をAlgolに取り入れさせ、それが他の多くの言語にも広まっていきました。

2. 関数型 Lispでは関数が第一級オブジェクトです。つまり、整数やストリングなどと同じデータ型であり、リテラル表現を持ち、変数に格納したり、引数として渡したりできます。

3. 再帰 再帰は数学の概念としては以前からありましたが、Lispが最初の再帰をサポートするプログラミング言語でした。(関数が第一級オブジェクトであることに暗黙的に含まれています。)

4. 変数の新しい概念 Lispでは全ての変数が実質的にポインタです。型を持つのは値であって、変数ではありません。変数への代入や束縛は、ポインタのコピーを意味します。

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

6. 式で構成されるプログラム Lispのプログラムは式の木構造で、各式は値を返します。(一部のLispでは式が複数の値を返すこともできます。)これは、Fortranやその後の多くの言語で区別されている式と文とは対照的です。

Fortranでこの区別が自然だったのは(パンチカードを入力形式としていたことから予想できるように)その言語が行指向だったためです。文をネストすることはできませんでした。そのため、数学の計算には式が必要でしたが、それ以外に値を返す必要はありませんでした。

この制限はブロック構造化された言語の登場で解消されましたが、その時にはもう遅すぎでした。式と文の区別は既に定着していました。それはFortranからAlgolに、そしてそれらの子孫言語にも広がっていきました。

式のみで構成される言語では、式をどのように組み合わせてもかまいません。たとえば(Arcの構文を使うと)

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

あるいは

(= x (if foo 1 2))

のように書くことができます。

7. シンボル型 シンボルは、ポインタを比較することで等価性をテストできるという点で、文字列とは異なります。

8. コードを表す記法としての木構造のシンボル

9. 常に利用可能な全言語 読み取り時、コンパイル時、実行時の区別がほとんどありません。 読み取り時にコードを実行したり、コンパイル時にコードを読み取ったり、実行時にコードをコンパイルしたりできます。

読み取り時にコードを実行できるため、Lispの構文をユーザーが書き換えられます。コンパイル時にコードを実行するのがマクロの基礎になっています。実行時にコンパイルするのがEmacs のようなプログラムでLispを拡張言語として使う基礎になっています。そして実行時に読み取るのがs式を使ってプログラム間で通信する仕組みの基礎になっています。これは最近XMLとして再発明されました。

Lispが最初に発明された当時、これらのアイデアはごく一般的なプログラミング実践からは程遠いものでした。それは1950年代後期の利用可能なハードウェアに大きく依存していました。

時間とともに、主流の言語に体現された「デフォルトの言語」は徐々にLispに近づいてきました。1-5は今や広く普及しています。6は主流に登場し始めています。Pythonには7の形態があるものの、それを表す構文はないようです。8は(9とともに)Lispマクロを可能にするものですが、それ以外の言語ではまだ固有のものとなっています。おそらくその理由は、(a)あのカッコが必要だからか、それと同じくらい悪いものが必要だからで、(b)その最後の一歩の力を加えると、もはや新しい言語を発明したとは言えず、Lispの新しい方言を設計したにすぎないからだと思われます。

現代のプログラマにとって有用ではありますが、Lispの特徴を他の言語の偶発的な手段からの違いとして説明するのは奇妙です。それはおそらくMcCarthyの考え方ではなかったでしょう。Lispは Fortranの間違いを修正するために設計されたのではなく、計算の公理化を試みる過程で生み出されたものだったと思われます。