From: Sam S. <sd...@gn...> - 2007-10-08 15:22:29
|
Sam Steingold wrote: > Eli Bendersky wrote: >> Consider this code: >> >> (defun printer (val) >> (lambda () (format t "~a~%" val))) >> >> (setq printer-of-10 (printer 10)) >> (funcall printer-of-10) >> >> It prints "10" as expected. However, consider this code: >> >> (defvar val 12) >> (funcall printer-of-10) >> >> It prints 12 ! > > this is, of course, not compliant. > to get the compliant behavior, you will need to compile the code, > e.g., by adding (declare (compile)) to the printer definition. > > ISTR that this behavior was implemented intentionally to ease > interactive development, because "usually" the printer above would be > followed by a (forgotten) defvar. on a second thought (and after looking at the source code :-), I think I can explain the CLISP behavior better. this is _interpreted_ code. when printer-of-10 is executed and val is evaluated (after defvar!), we see a globally special symbol val which can have only a global symbol-value (not a local binding), and thus we are compelled to evaluate it to 12. this is an artifact of interaction between global special declarations and code interpretation. the compiled code does not exhibit this behavior because the compilation eliminates the symbol val from the compiled code, so defvar cannot affect it. note that (let ((val 42)) (funcall printer-of-10)) prints 10 before defvar and 42 after. hth. Sam. |