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))))