2

I'm doing a small project just for fun, and I added eval support for it to make debug easier. But later I found a problem:

(let ((x 1))
    (eval (1+ x)))

(defun foo (x form)
    (eval form))
(foo 1 '(1+ x))

Code above won't work. Could someone please explain why and how to work it around? Thanks very much.

4

1 回答 1

5

首先,虽然

(let ((x 1))
  (eval (1+ x)))

可能看起来它确实有效(它肯定会做某事),它可能没有做,你打算做什么。eval是一个常规函数,因此它接收由调用者评估的参数。实际上,您eval使用整数值调用2-- 然后将其“评估”(因为整数是自引用的)到结果值2.

(defun foo (x form)
  (eval form))

更容易诊断故障。运行时词法绑定不是一流的对象,而是由解释器/编译器在幕后维护的东西。常规函数(如eval)无法访问在其调用点定义的词法变量。

一种解决方法是使用特殊变量:

(defun foo (x form)
  (declare (special x))
  (eval form))

该声明告诉您的 lisp 实现,它x应该在其范围内动态绑定。

于 2013-06-26T07:06:57.153 回答