理解LISP中的"let"表达

tom*_*oka 5 lisp common-lisp let

我是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)
Run Code Online (Sandbox Code Playgroud)

Rai*_*wig 11

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

Lisp中的风格与约会

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

(defvar *x* 1)
Run Code Online (Sandbox Code Playgroud)

那么你的代码是:

(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
Run Code Online (Sandbox Code Playgroud)

跑:

? (f 2)
10
Run Code Online (Sandbox Code Playgroud)