2

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.

Charlim
  • 521
  • 4
  • 12
  • Quines are easy with reader variables, but maybe this is considered cheating. Maybe try with anonymous functions? – coredump Feb 11 '19 at 08:37

1 Answers1

7
(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.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • 1
    Note that you can work around this in a slightly horrible way by adding suitable `(declare (special program))` declarations as the first thing in the two binding forms. –  Feb 17 '19 at 17:00