【入門】Common Lisp その10【質問よろず】
■ このスレッドは過去ログ倉庫に格納されています
0679デフォルトの名無しさん
2014/02/19(水) 20:54:08.49(defun my-for-each (fn lst)
(when lst
(funcall fn (car lst))
(my-for-each fn (cdr lst))))
fn に my-for-each を定義する関数が渡されることがある。
例えば、
(my-for-each
(lambda (a)
(print a)
(defun my-for-each (fn lst) nil))
'(a b c))
このような場合、ループせずに一回目の呼び出しで終了しなきゃならない。
つまり my-for-each は末尾再帰ではなく、末尾呼出と呼ぶべきもの。
で、末尾呼出はただのジャンプ命令に変換しちゃいけない。
毎回同じ場所にジャンプできるとは限らないし、
arity の違う関数に束縛されてるかもしれないから。
一応 Common Lisp では
「関数fの呼び出し中にfの束縛が変更されないと仮定してよい」
というような規則があるので、
コンパイラによってはループに変換するかもしれない。
でもそれはコンパイラの方針によるのであって、
「賢いコンパイラなら」というのは誤り。
動的なコード変更を重視する処理系なら、このような仮定はしない。
まあ、色々あって、Common Lisp では再帰とループは使い分けるのが普通だと思う。
■ このスレッドは過去ログ倉庫に格納されています