为什么LET在我的quine中不能和EVAL一起玩?

Cha*_*lim 2 lisp eval common-lisp quine

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

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))
Run Code Online (Sandbox Code Playgroud)

这不起作用,SBCL和CLISP都抱怨PROGRAM没有约束.但是,我确实发现使用DEFPARAMETER与LET不同,确实有效:

(progn
  (defparameter program
                '`(progn
                    (defparameter program
                                  ',program)
                    (print (eval program))))
  (print (eval program)))
Run Code Online (Sandbox Code Playgroud)

对于第二个例子,打印的代码和编写的代码之间的唯一区别是空格和大小写,我可以轻松修复.但是,我仍然不明白为什么我的第一次尝试不起作用.正如我所看到的,唯一的区别是变量的范围,但它似乎无关紧要,因为我正在评估包含它的范围内的程序.

Rai*_*wig 7

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))
Run Code Online (Sandbox Code Playgroud)

Common Lisp标准说eval:

评估当前动态环境和null 词法环境中的表单.

由于program是一个词汇变量,它是不可见的eval.