lispcommon-lispevalquine

Why does LET not play nice with EVAL in my quine?


I was trying to write a Common Lisp quine. I figured one of the simplest options was as follows:

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

This does not work, SBCL and CLISP both complain that PROGRAM is unbound. I did, however, find that using DEFPARAMETER, unlike LET, does work:

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

For the second example the only difference between the code printed and the code written is the whitespace and capitalization, which I can easily fix. I still, however, do not understand why my first attempt was not working. As I see it, the only difference is the scoping of the variable, but it really seems like it shouldn't matter since I'm evaluating program within the scope that contains it.


Solution

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

    The Common Lisp standard says about eval:

    Evaluates form in the current dynamic environment and the null lexical environment.

    Since program is a lexical variable, it's not visible to eval.