Shammer's Philosophy

My private adversaria

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

【LISP繰り返し Hack 】do を展開してみる・その1 - Shammerismの続きで、tagbody と go を使ってみた。dolist のようなものを想定して書いた。

? (let ((target '("XXX" "YYY" "ZZZ")))
    (tagbody
      loop-start
        (let ((x (car target)))
          (if (null x) (go loop-end))
          (format t "~A~%" (concatenate 'string x " is ok."))
          (setf target (cdr target))
          (go loop-start))
      loop-end
        (format t "Finish!!!~%")))
XXX is ok.
YYY is ok.
ZZZ is ok.
Finish!!!
NIL
?

とりあえずだが・・・tagbody の中でラベルの定義と、go によってそのラベルにジャンプすることができる。return-from をやろうとしたら、以下のようなエラーが出た。

? (let ((taget '("ZZZ" "YYY" "XXX")))
    (tagbody loop-tag
      (let ((x (car target)))
        (if (null x) (return-from loop-tag))
        (format t "~A~%" (concatenate 'string x " is ok."))
        (setf target (cdr target))
        (go loop-tag))))
> Error: While compiling an anonymous function :
>        Can't RETURN-FROM block : LOOP-TAG., in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: continue compilation ignoring this form
> Type :? for other options.
1 >

loop-tag から抜けるために return-from の引数でそれを指定したが、この使い方は間違いのようだ。この書き方だと一気に抜けることはできない。上に書いたように、終わりのためのラベルを用意し、そこに遷移させるようにするようだ。return-from はおそらく block と組み合わせて使うのだろう。それも後日やってみよう。