了解 LISP 中的 "let" 表达式

Understanding "let" expression in LISP

我对 lisp 非常陌生,以前有过函数式编程的经验(Haskell,SML)。为什么此代码返回 14,而不是 10(即 1 + 2y + 3 + 1)?

(defvar x 1)

(defun g (z)
  (+ x z))

(defun f (y)
  (+ (g 1)
     (let ((x (+ y 3)))
        (g (+ y x)))))

(f 2)

原因是您使用的是带有 dynamic binding 的 Lisp 方言(link Emacs Lisp 文档对此有很好的描述)。

详细地说,您的程序的行为方式是因为 let 表达式为 x 创建的新绑定在 [=13= 时取代了 (defvar x 1) ] 从 let 表达式中调用。因此,g 函数不是将 1 添加到它的参数,而是添加 x 的当前值,当在 let 表达式中时该值是 5。

因为你使用了(DEFVAR X 1),它声明了X是一个全局特殊变量。然后这会导致 X 的所有其他后续绑定使用动态绑定:在 (LET ((X ....

Lisp 中的风格和约定

Lisp 中的约定:对特殊变量使用 *X* 而不是 X

(defvar *x* 1)

你的密码是:

(defvar *x* 1)   ; global special variable *X*

(defun g (z)
  (+ *x* z))     ; use special variable *X*

(defun f (y)
  (+ (g 1)
     (let ((x (+ y 3)))    ; lexical binding of X
        (g (+ y x)))))     ; use lexical binding of X

运行:

? (f 2)
10