Posted 2021-10-28 17:40:05 GMT
コード整理で関数の分割や統合を行なっている際に、return-from
等で脱出する場所を上手く小分けにできなかったり、まとめられなかったりする局面がたまにありますが、block
のタグやtagbody
のラベルをクロージャーにして渡してしまえば簡単だということに気付きました。
例えば、このような一つの関数を
(defun foo (int)
(when (oddp int) (return-from foo (values int 'odd)))
(print (+ 1 int))
(print "fin"))(foo 99)
→ 99
odd
(foo 98)
▻
▻ 99
▻ "fin"
→ "fin"
二つの関数に分解できます。
(defun bar (int xit)
(when (oddp int) (funcall xit int))
(print (+ 1 int)))(defun foo (int)
(bar int (lambda (int) (return-from foo (values int 'odd))))
(print "fin"))
(foo 99)
→ 99
odd
(foo 98)
▻
▻ 99
▻ "fin"
→ "fin"
tagbody
のラベルも同様です。
(defun foo (int &aux ans)
(tagbody
(bar int (lambda (int)
(setq ans int)
(go X)))
(print "fin")
X (return-from foo ans)))
リファクタリング作業等ではたまに使えることもあるかもしれません。
ちなみに、tagbody
のラベルもblock
のブロック名もレキシカル変数とは違って有限エクステントなので、式の外へは持ち出せませんので注意しましょう。
■
HTML generated by 3bmd in LispWorks 7.0.0