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先生と共になんらかの協力はあったようです。
今回は、その野心的で先進的なアイデアのいくつかを紹介したいと思います。
LISP 1.5では、元のLISPでM式とS式とあったうち、S式だけでもプログラミングできるじゃないか、ということでS式のみのサポートでしたが、LISP 2では、ユーザーは、ALGOLライクな記述をし、それをお馴染のS式に変換するという流れになります。
ALGOL記法は、SL(Souce Language)と呼ばれ、S式記法は、IL(Intermediate Language)と呼ばれますが、ユーザーが直接IL(S式)を書いても良いようです。
メリットとしては、ALGOLのソースコードをコピペできるので良い的なことが述べられていたりしますが、かなりALGOLです。
実際どんな感じかというと、
% fibonacciinteger 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)))))
のように変換され、コンパイルされるとのことです。
上記のソースコードから察せられるようにALGOLと同じようにLISP 2には型指定があります。
これは主に高速化のためのもので、Common Lispと同じく型指定はオプショナルで、指定しない場合は、一番汎用的な型になります(LISP 2だとSymbolタイプ)
これもALGOL由来ですが、レキシカルスコープを採用しています。
もうALGOLにしてしまいたかった感が溢れている気はしますが、大分コンパイラ指向のようなので当然なのかもしれません。
そうなるとクロージャーは実現されていたのかが気になりますが、エクステントは無限という記述は見付かりませんし、どうもALGOLと同じに見えます。
しかし、レキシカルスコープ採用のLISP方言としては最初のものではないでしょうか。
これまた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も全く無関係でもないのかなあという気がしています。
LISP 2では、ひとまとまりのモジュールをsectionと呼び、
symbol$section
と記述できます。
これは、Common Lispで書くなら、
section::symbol
という風になりますが、順番が逆です。
sectionはCommon Lispと同じく大規模開発での名前競合を防ぐ目的で導入されたようです。
MIT系のLisp方言では、
'(0 1 2 3) ≡(quote (0 1 2 3))
と記述でき、これはリーダーマクロで実現されていますが、MacLISPにリーダーマクロとして導入されたのは、1969年で、4年程先行しています。 はっきりしたことは判りませんが、もしかしたら、LISP 2の記法を取り入れたのかもしれません。
Schemeだとレキシカルスコープだけ(今のSchemeは)ですが、動的変数もサポートしていたようです。
動的変数は、OWN
宣言をします。
先進的なのかどうかは議論が分かれそうですが、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)
となります。
先進的というか、そのまま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が沢山の資料を公開しています。
興味のある方は是非眺めてみて下さい。
■
HTML generated by 3bmd in LispWorks 7.0.0