flet in Common Lisp / elisp

Common Lispelispのfletには違いがある。

Common Lispだとfletで定義されたローカル関数内に同名の関数があった場合、外側のが参照される。

(defun fact (x)
  (if (zerop x) 1
      (* (fact (1- x)) x)))
(flet ((fact (x)
         (* 2 (fact x))))               ; global fact
  (fact 3)) ; => 12

elispの場合はローカル関数が参照される。

(defun fact (x)
  (if (zerop x) 1
      (* (fact (1- x)) x)))
(flet ((fact (x)
         (* 2 (fact x))))               ; local fact
  (fact 3)) ; 無限ループ

つまり、labelsと同じような挙動だ。

(labels ((f (x)
           (if (zerop x) 1
               (* (f (1- x)) x))))      ; local f
  (f 3)) ; => 6
(flet ((f (x)
           (if (zerop x) 1
               (* (f (1- x)) x))))      ; local f
  (f 3)) ; => 6