Lisp 为什么让我们在我的奎因中不好好地玩EVAL?

Lisp 为什么让我们在我的奎因中不好好地玩EVAL?,lisp,common-lisp,eval,quine,Lisp,Common Lisp,Eval,Quine,我想写一个普通的口齿不清的奎因。我认为最简单的选择之一如下: (let ((program '`(let ((program ',program ) (print (eval program))))) (print (eval program)))) 这不起作用,SBCL和CLISP都抱怨程序未绑定。但是,我发现使用DEFPARAMETER与LET不同,它确实有效: 对于第二个示例,打印的代码和编写的代码之间的唯一区别是空格和大写,我可以很容易地修复它

我想写一个普通的口齿不清的奎因。我认为最简单的选择之一如下:

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))
这不起作用,SBCL和CLISP都抱怨程序未绑定。但是,我发现使用DEFPARAMETER与LET不同,它确实有效:

对于第二个示例,打印的代码和编写的代码之间的唯一区别是空格和大写,我可以很容易地修复它们。然而,我仍然不明白为什么我的第一次尝试没有成功。在我看来,唯一的区别是变量的作用域,但这似乎并不重要,因为我在包含它的范围内评估程序

(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))
通用Lisp标准说明了
eval

在当前动态环境和空词汇环境中计算表单


由于
program
是一个词法变量,它对
eval

来说是不可见的,奎因很容易使用读者变量,但这可能被认为是作弊。也许可以尝试使用匿名函数?请注意,您可以通过在两种绑定形式中添加适当的
(declare(special program))
声明作为第一件事来解决这一问题。
(let ((program '`(let ((program ',program )
                   (print (eval program)))))
  (print (eval program))))