为什么让LET与我的EVAL搭配不好?

时间:2019-02-11 07:03:01

标签: lisp common-lisp eval quine

我试图写一个Common Lisp quine。我认为最简单的选择之一如下:

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))

这不起作用,SBCL和CLISP都抱怨PROGRAM未绑定。但是,我确实发现使用DEFPARAMETER与LET不同,确实有效:

(progn
  (defparameter program
                '`(progn
                    (defparameter program
                                  ',program)
                    (print (eval program))))
  (print (eval program)))

对于第二个示例,打印的代码和编写的代码之间的唯一区别是空格和大写字母,我可以很容易地解决。但是,我仍然不明白为什么我的第一次尝试没有奏效。正如我所看到的,唯一的区别是变量的范围,但实际上似乎没有关系,因为我正在包含它的范围内评估程序。

1 个答案:

答案 0 :(得分:7)

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))

Common Lisp标准规定了eval

  

在当前的动态环境和空的词法环境中评估 form

由于program是一个词法变量,因此eval不可见。