Shammer's Philosophy

My private adversaria

【LISP繰り返し Hack 】do を展開してみる・その1

一応、LISP でも繰り返し構文がある。一部の書籍だと、関数型言語は繰り返し構文でなく、再帰で繰り返しを実現する、、、とか書いているがとんでもない。黎明期にはそういう時期もあったかもしれないが、そもそも関数型とは、変数の型に整数型、文字列型、浮動小数点型とかある他に「関数型」というのがあっただけと思われる。しかし、それ以外にも関数型かどうかとは全然関係ない様々な特徴もあり、関数型とは何かよくわかっていない人が LISP に触れて、関数型かどうかとは全然関係ない、当時の LISP の特徴から、関数型とはこういうものだ、と当時の LISP の特徴をまとめただけじゃないかと・・・まあ、今となってはこの真偽を追求することも不可能だろうし追求したところで何か得られるかと言えばそうでもないので、、、この話はおしまい。
で、本題の繰り返しだが、基本となる do を展開してみたらこうなった。オリジナルのコードはこれ。

(do () () (format t "Hello.~%"))

まあ、終了条件がないので、実行すると延々と Hello. と出力され続けるが。これを macroexpand-1 で展開すると以下のようになる。

? (macroexpand-1 '(do () () (format t "Hello.~%")))
(BLOCK NIL (LET NIL (TAGBODY (GO #:G7809) #:G7808 (TAGBODY (FORMAT T "Hello.~%")) (PSETQ) #:G7809 (UNLESS NIL (GO #:G7808)))))
T
?

tagbody と go が使用されている。自分で書いたコードで思うようにループを抜けない、という場合は、tagbody と go の使い方を理解して、最悪は自分でこのレベルのコードを書けばいい、、、はず。