2ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

【入門】Common Lisp その10【質問よろず】

679 :デフォルトの名無しさん: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 では再帰とループは使い分けるのが普通だと思う。

199 KB
新着レスの表示

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50
名前: E-mail (省略可) :


read.cgi ver 05.02.02 2014/06/23 Mango Mangüé ★
FOX ★ DSO(Dynamic Shared Object)