Posted 2015-12-09 14:27:07 GMT

Lisp Advent Calendar 2015の9日目です。

最初期のLispといえば、元祖LISP 1.5ですが、LISP 1.5を継いだバージョン名としては、スタンフォードで主に開発されたLISP 1.6、日本のLISP 1.9、同じく日本の謎のLISP 1.7、等があります。

しかし、一見する所では、志を継いではいるのでしょうが、それぞれ開発コミュニティとしては無関係のようです。

別々の開発コミュニティなのに連番を付けるとは不思議ですが、まあ当時はそんなものだったのかもしれません。

ちなみに、LISP 1からLISP 1.5への流れは大元のMITのもので関連がある流れです。

そこで今回紹介するLISP 2ですが、1965年頃にLISP 1.5の後継となるべくARPAの支援の元、SDC(System Development Corporation)という企業が主となって開発が開始されたもので、野心的な試みが盛り込まれています。

LISP 2にはMcCarthy先生は直接の関与はないようですが、Minsky先生と共になんらかの協力はあったようです。

今回は、その野心的で先進的なアイデアのいくつかを紹介したいと思います。

先進的な所 その1: 記述用言語と中間言語を分けた (S式は直接書かない)

LISP 1.5では、元のLISPでM式とS式とあったうち、S式だけでもプログラミングできるじゃないか、ということでS式のみのサポートでしたが、LISP 2では、ユーザーは、ALGOLライクな記述をし、それをお馴染のS式に変換するという流れになります。

ALGOL記法は、SL(Souce Language)と呼ばれ、S式記法は、IL(Intermediate Language)と呼ばれますが、ユーザーが直接IL(S式)を書いても良いようです。

メリットとしては、ALGOLのソースコードをコピペできるので良い的なことが述べられていたりしますが、かなりALGOLです。

実際どんな感じかというと、

% fibonacci integer function fib(n); integer n; if n < 2 then n else fib(n - 1) + fib(n - 2); end;

のように書くと、

( function ( fib integer ) ( ( n integer ) ) ( if ( ls n 2 ) n ( plus ( fib ( difference n 1 ) ) ( fib ( difference n 2 ) ) ) ) )

のように変換され、コンパイルされるとのことです。

先進的な所 その2: 型指定がある(そして指定はオプショナル)

上記のソースコードから察せられるようにALGOLと同じようにLISP 2には型指定があります。

これは主に高速化のためのもので、Common Lispと同じく型指定はオプショナルで、指定しない場合は、一番汎用的な型になります(LISP 2だとSymbolタイプ)

先進的な所 その3: レキシカルスコープの採用

これもALGOL由来ですが、レキシカルスコープを採用しています。

もうALGOLにしてしまいたかった感が溢れている気はしますが、大分コンパイラ指向のようなので当然なのかもしれません。

そうなるとクロージャーは実現されていたのかが気になりますが、エクステントは無限という記述は見付かりませんし、どうもALGOLと同じに見えます。

しかし、レキシカルスコープ採用のLISP方言としては最初のものではないでしょうか。

先進的な所 その4: Common LispでいうSETFがある

これまたALGOLの左辺値が由来なんだと思いますが、Common LispでいうSETFがあり、これは、formal variable/assignment-expression/locativeと呼ばれます。

LISP 2では、配列だけでなく、リストやバイト列に対して代入可能です。

car x ←42;

というのは、

( set ( car x ) 42 )

となり、そのままCommon Lispの SETF です。

SETF の由来は、ピーター・ドイチュ氏〜アラン・ケイ氏という話が有名ですが、そのドイチュ氏の論文は1973年なので8年位はLISP 2の方が先行しています。

また SETF の機構を全面的に取り入れたMITのLISPマシンの論文にもLISP 2の文献の引用があるので、LISP 2も全く無関係でもないのかなあという気がしています。

先進的な所 その5: モジュール化の為の名前空間の仕組みがある

LISP 2では、ひとまとまりのモジュールをsectionと呼び、

symbol$section

と記述できます。

これは、Common Lispで書くなら、

section::symbol

という風になりますが、順番が逆です。

sectionはCommon Lispと同じく大規模開発での名前競合を防ぐ目的で導入されたようです。

先進的な所 その6: Quoteが『'』で表現されている

MIT系のLisp方言では、

'(0 1 2 3) ≡(quote (0 1 2 3))

と記述でき、これはリーダーマクロで実現されていますが、MacLISPにリーダーマクロとして導入されたのは、1969年で、4年程先行しています。 はっきりしたことは判りませんが、もしかしたら、LISP 2の記法を取り入れたのかもしれません。

先進的な所 その7: 動的変数もサポートする

Schemeだとレキシカルスコープだけ(今のSchemeは)ですが、動的変数もサポートしていたようです。

動的変数は、 OWN 宣言をします。

先進的?な所 その8: Arcのifと同じ形式

先進的なのかどうかは議論が分かれそうですが、LISP 2の if は新しめのLisp方言で取り入れられるArcのifの形式と全く同じです。

まあ、暗黙のprognがないオリジナルの COND をそのまま IF という名前にしただけとも言えますが…。

if p0 then c else if p1 then a0 else a1;

は、

( if p0 c p1 a0 a1 )

となります。

先進的?な所 その9: 参照がある

先進的というか、そのままALGOLじゃないかという感じですが、参照があります。

参照型の変数は、 loc 宣言をします。

ALGOLのソースコードを流用したかったようなので、必要な機能だったのかもしれません…。

まとめ

LISP 2の先進性についていかがだったでしょうか。

一言で簡単に言ってしまうなら、LISPとALGOLの融合といえると思います。

かれこれ50年前のアイデアですが、Common Lispを20年ばかり先取りしている所も結構ありますし、ALGOLとの融合でいえば、Schemeに10年は先行します。

また、湧いては消えていく『LISPで中置記法』も50年前には既に真面目に取り組まれていたのだなあと感慨深いものもあります。

何かの文献で、竹内郁雄先生がLISP 2について触れられていたと思いますが、確か『失敗したプロジェクト』と表現されていたと思います。

実際の所、野心的過ぎたのか、実験的な処理系が試作されたのみで、LISP 2が一方言として確立したものとなることはなかったようです。

LISP 2については、Software Preservation Groupが沢山の資料を公開しています。

興味のある方は是非眺めてみて下さい。

■

