flet相当于let *?

时间:2011-07-16 23:32:09

标签: lisp elisp

flet*没有flet因为let* let我可以在emacs lisp中找到 - 所以这四种选择中的任何一种都更具惯用性用于定义由flet定义的单个函数多次使用的函数?在此示例中,add1是我想在add1twice内重用但未在其外部使用的函数。

选项1

(defun add2 (x)
  (flet ((add1 (x) (1+ x)))
    (flet ((add1twice (x)
              (add1 (add1 x))))
      (add1twice x))))

选项2

(defun add2 (x) 
  (flet ((add1twice (x)
            (flet ((add1 (x) (1+ x)))
              (add1 (add1 x)))))
     (add1twice x)))

选项3

(defun add2 (x)
  (flet ((add1twice (x)
            (let (add1)
              (fset 'add1 (lambda (x) (1+ x)))
              (add1 (add1 x)))))
      (add1twice x)))

选项4

(labels ((add1 (x) (1+ x)))
  (defun add2 (x) 
    (flet ((add1twice (x)
              (add1 (add1 x))))
      (add1twice x))))

(所有这些产生相同的结果。)

3 个答案:

答案 0 :(得分:1)

虽然在the documentation for flet中不太清楚,但它的宏观扩展表明它容忍顺序绑定:

(defun add2 (x)
  (flet ((add1 (x) (1+ x))
         (add1twice (x)
           (add1 (add1 x))))
    (add1twice x)))

文档提到建立“let - 样式绑定” - let* - 但上面的定义仍有效。

答案 1 :(得分:1)

您还有labels用于fletlet*用于let

答案 2 :(得分:0)

顺便说一句,除了使用cl-labels,您还可以通过let*手动完成此操作:

(defun add2 (x)
  (let* ((add1 (lambda (x) (1+ x)))
         (add1twice (lambda (x) (funcall add1 (funcall add1 x)))))
    (funcall add1twice x)))

诚然,它比cl-fletcl-labels更为冗长。