#出会い
平成28年3月、五味先生の「はじめてのLisp関数型プログラミング」を読みました。そこでISLispのことに触れていました。ISLisp規格は日本人研究者の案が基となった国際規格であり、その日本人研究者の中には、あの湯浅先生の名前がありました。興味がわいた私は早速、規格書を読み始めました。読み進めるうちに、ISLisp規格はコンパクトで一貫性のある優れた設計であることが、わかってきました。惚れ込んだ私は自分でもISLisp処理系を制作することにしました。4月に制作にとりかかり、7月にはほぼ完成しました。その間に得た情報、知見などをお伝えしたいと思います。
#ISLisp規格誕生の経緯
1980年代にCommon Lisp規格が制定され標準化に向かいました。しかし、問題もありました。Common Lispの仕様は巨大でした。文献1からそのあたりのことを引用します。
ISLISPの標準化
一方、Common Lispの発表以来、その言語仕様の巨大さから、実行効率や学習・利用の面からの問題が指摘されてきた。Common Lispの抱えるこのような問題を解決し、コンパクトで効率が高く、かつ使いやすいLisp言語を目標として、1987年にSC22にWG16が設置されてISLISPの標準化が開始された。
LISPの核部分については伊藤、湯浅、梅村先生等のKL(Kernel LISP)が採用され、オブジェクト指向部分についてはCLOSをベースにしたILOSが採用されたとのことです。
#具体例
ISLispはCommon Lispをベースにしていますが、圧倒的にコンパクトです。組込関数で180個程度、特殊形式が50個程度です。Common Lispを洗練させ、Scheme的なところも取り入れています。例えば次のようです。
(1)コンパクトさ
convertですべての型変換をまとめています。
Easy-ISLisp Ver0.43
> (convert "123" <list>)
(#\1 #\2 #\3)
> (convert 123 <string>)
"123"
>
cadr caddr のようなものをeltにまとめています。
> (elt "123" 1)
#\2
> (elt '(1 2 3) 1)
2
> (elt #(a b c) 1)
B
>
このように1つの関数、特殊形式に機能を集約することにより、関数を少なくしています。
(2)シンプルさ
Schemeと同様、lambdaは#'を付けずにどこでも使えます。Common Lispはlambdaにつき#'を省略するために、マクロを使っています。
> (apply (lambda (x y) (+ x y)) '(1 2))
3
>
ILOSはメソッド結合は固定で、補助メソッド結合は :before と :after、 :around だけです。
また、次のようなクラス承継はエラーになります。
> (defclass a ()())
(defclass b (a) ())
(defclass c (a) ())
(defclass d (b c) ())
A
> B
> C
> Super class has common parents at defclass (B C)
>
クラスdのように兄弟に共通の親を指定するとエラーになります。このためCLOSのようにトポロジカルソートをしない分、処理系は簡素になっています。
(3)先進性
エラー処理はCommon Lisp、Schemeと比べて充実しています。次の例は例外オブジェクトを捕獲するものです。エラーはクラスにより整理されています。
(defconstant foo
(catch 'c-parse-error
(with-handler
(lambda (c) (throw 'c-parse-error c))
(parse-number "foo")))
)
Easy-ISLisp Ver0.43
> foo
<instance>
> (class-of foo)
<class parse-error>
> (subclassp (class-of foo) (class <error>))
T
>
#代表的処理系
OKI-ISLispがWindows用として公開されています。
http://islisp.org/jp/download-jp.html
東北大学伊藤研究室においてTISL処理系がソースコード付きで公開されています。
http://www.ito.ecei.tohoku.ac.jp/TISL/
他にも商用のOpenLispなどがあります。
http://islisp.org/jp/other-ISLisp-jp.html
私は自作処理系(EISL)を制作するにあたり、OKI-ISLispを参照させていただきました。OKI-ISLispは1990年代に制作されました。ISLispを普及させる必要性からVM方式になっています。当時のパソコンはC言語処理系を装備しておらず非力で起動にも時間がかかることから、敢えてVM方式をとったようです。現在のパソコンは、かつてのスーパーコンピューター並みの計算機パワーを持っていますし、GCCなどのコンパイラが高速に動作します。現在であればGCLと同様、C言語へのトランスレート方式の方が高速なコードが得られるでしょう。
#処理系制作のヒント
平成28年の4月から仕事の合間の土日を利用して、おおよそ3か月でほぼ完成しました。仕様がコンパクトですので、個人で制作、メンテナンスすることは十分に可能です。Scheme処理系ですと継続、call/ccに大いに悩まされるのですが、ISLispはシンプルで素直です。割と簡単に実装できると思います。
規格に準拠しているかどうかを点検するのに、公開されている検証システムを使うことができます。次のページから入手可能です。
http://islisp.org/jp/download-jp.html
これは膨大なテストケースから構成されています。かなり完成度が高くなってからでないと、この検証システムは動作しないだろうと思います。私は簡単なマクロを作り、この検証システムのテストケースを部分的に取り出して、テストをしていました。これが全部、パスすれば、ほぼISLisp仕様を満たしていると思います。
ILOSやエラーの仕様は、独学ではなかなか理解できないことも多く、五味先生に助言をいただきました。先生はFaceBookでISLispの公開グループを公開されています。私はここで、あれこれと基本的なことを教えていただきました。アドレスは下記のとおりです。
https://www.facebook.com/groups/islisp/?fref=ts
制作の終盤に差し掛かった頃、M.Hiroiさんに助言を仰ぎました。Hiroiさんはいろいろテストしてくださり、間違いを修正することができました。静的スコープにしたはずが、動的スコープになっていたりで冷や汗をかきましたが、お蔭でだいぶ完成度を上げることができました。
改めて五味先生とM.Hiroiさんに感謝いたします。
#思考の道具として
20年ほど前になりますが、古本屋で「考える道具としてのLisp入門」という本を見かけました。現在では入手困難のようです。購入しておけばよかったと後悔しています。Lispはプログラミング言語であるだけでなく、思考をとりまとめ、表現する手段でもあると私は思います。創始者のマッカーシー博士はLisp考案にあたり、自分なりのチューリングマシンが欲しかった、と聞いたことがあります。数学畑出身の博士は、もちろんゲーデルの不完全性定理のことも知っていらっしゃったと思います。「ゲーデルはLispを思いついておくべきだった。もし彼がLispを思いついていたならば彼の不完全性定理の証明はもっと簡単なものになっただろう」とはミンスキーのジョークですが、理論的なバックもしっかりした言語であることは論をまたないでしょう。
思考実験をするのにISLispは向いていると思います。こういう目的のためには多くの組み込み関数を必要としません。コンパクトな方が扱いが楽なはずです。チャイティンは独自のLisp処理系を用い、てゲーデルの不完全性定理の証明を示しています。こんなことの理解、再現にISLispは向いているように思います。
#実験の道具として
自作のISLisp処理系(以下「EISL」)はC言語の標準機能しか使っていないので、多くのOS,Cコンパイラでコンパイル、実行可能です。GPUで有名なNVIDIA社のCUDAのためのコンパイラNVCCでもコンパイル可能でした。人気のラズベリーパイもメモリをたくさん積んでいますし、Linuxですから、EISLも十分に動作するだろうと思います。
そうすると、Cのライブラリを介してハードウェアを直接操作する、といったことが簡単にできます。必要なライブラリを組み込んで処理系をコンパイルしなおし、必要な独自関数を組み込んでしまうことが可能です。ISLispはILOSオブジェクト指向も搭載していますので、ロボット制御のような実験的なことにも、使えるだろうと思います。C言語で扱えることはすべて、EISLに組み込むことが可能です。C言語で細々としたことを記述するのはなかなか骨がおれます。Lispの組み込み関数にしてしまえば、試行錯誤しつつ実験を繰り返すことも、苦にならなくなるように思います。
#チュートリアルなど
M.HiroiさんがISLispに興味をもち、入門文書を公開なさっています。下記のページです。
http://www.geocities.jp/m_hiroi/clisp/islisp.html
#コマーシャル
本文に登場した自作ISLisp処理系のことをKindleより電子書籍にて販売しています。よかったら立ち読みしていってください。ソースコードを付録としています。現在のところインタプリタのみなのですが、いずれC言語へのトランスレータを付加したいと思っています。以前、自作Scheme処理系のNormalにC言語へのトランスレータを考案、実装しました。その経験とノウハウをISLispに移転させたいと思っています。
追記 最新版ではコンパイラが装備されています。GaucheのようなVM型の数倍から数十倍の実行速度です。また、C言語をS式の中に取り込む機能も追加されています。(平成29年8月追記)
#参考文献
1.「LispのISO標準規格ISLISPの処理系の研究開発」湯浅 太一、梅村 恭司、長坂 篤 IPA技術発表会 http://islisp.org/docs/ISLisp-IPA-report.pdf
2. 「はじめてのLisp関数型プログラミング」 五味 弘 著 技術評論社
3. 「考える道具としてのLisp入門」 難波 和明、 安西 祐一郎 著 共立出版
4.「知の限界」 G.J.チャイティン 著 黒川 利明 訳 星雲社