elisp为什么能在let里定义递归函数?

``````(defun my-fact (input)
"Return factorial of INPUT."
(let ((my-inside-fact #'(lambda (to-multiply next-gen)
(if (< to-multiply 1)
next-gen
(funcall my-inside-fact (- to-multiply 1) (* next-gen to-multiply))))))
(funcall my-inside-fact (- input 1) input)))

(message "%s" (my-fact 10))
;; => 3628800
``````

``````Debugger entered--Lisp error: (void-variable my-inside-fact)
(funcall my-inside-fact (- to-multiply 1) (* next-gen to-multiply))
(if (< to-multiply 1) next-gen (funcall my-inside-fact (- to-multiply 1) (* next-gen to-multiply)))
``````

``````CL-USER> (defvar my-inside-fact)
MY-INSIDE-FACT
CL-USER> (defun my-fact (input)
"Return factorial of INPUT."
(let ((my-inside-fact #'(lambda (to-multiply next-gen)
(if (< to-multiply 1)
next-gen
(funcall my-inside-fact (- to-multiply 1) (* next-gen to-multiply))))))
(funcall my-inside-fact (- input 1) input)))
MY-FACT
CL-USER> (my-fact 10)
3628800 (22 bits, #x375F00)
``````
2 个赞

``````(defun my-fact (input)
"Return factorial of INPUT."
(letrec ((my-inside-fact
#'(lambda (to-multiply next-gen)
(if (< to-multiply 1)
next-gen
(funcall my-inside-fact (- to-multiply 1) (* next-gen to-multiply))))))
(funcall my-inside-fact (- input 1) input)))

;; Expands to

(defun my-fact (input)
"Return factorial of INPUT."
(let
(my-inside-fact)
(setq my-inside-fact
(function
(lambda
(to-multiply next-gen)
(if
(< to-multiply 1)
next-gen
(funcall my-inside-fact
(- to-multiply 1)
(* next-gen to-multiply))))))
(funcall my-inside-fact
(- input 1)
input)))
``````
2 个赞