Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane
From: Sam Steingold <sds <at> gnu.org>
Subject: Re: defvar affecting captured closure variables ?
Newsgroups: gmane.lisp.clisp.general
Date: Monday 8th October 2007 15:22:18 UTC (over 9 years ago)
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.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
 
CD: 3ms