Subject: Re: Misuse of Dynamic Variables
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 11 Mar 2001 02:32:04 GMT
Newsgroups: comp.lang.lisp
Message-ID: <98eo34$2qkvc$1@fido.engr.sgi.com>
Kent M Pitman  <pitman@world.std.com> wrote:
+---------------
| ncohen@bridgenospamtrix.com (Neil Cohen) writes:
| > In MCL 4.0, if the name of  special variable is used as a parameter in a
| > function which itself creates a function, the value of the special
| > variable is used. [...]
| 
| Sounds like something to report the vendor.
+---------------

I missed this one too on first reading (though I'm mildly surprised
Kent didn't see it -- perhaps skimmed over it a little too quickly?).  ;-}
I had to run the example through CLISP and CMUCL (which give the same
results as MCL) and stare at it a bit before I noticed that "obviously"
the code is doing exactly the *RIGHT* thing!!  [Ref to old math joke...]

Neil's confusion is about when the value of the special is being used,
which is *not* when the closure is created, but when it's *called*. Let's
rewrite the example, using the *...* convention on the special (to avoid
picking up bad habits), and adding an auxiliary variable to capture the
value of the special at the time when the closure is created:

	> (defvar *spades* 2)
	*SPADES*
	> (defun foo (*spades*)
	    (let ((lexical-spades *spades*))
	      #'(lambda () (list  *spades* lexical-spades))))
	FOO
	> (funcall (foo 3))
	(2 3)
	> (setq *spades* 4)
	4
	> (funcall (foo 5))
	(4 5)
	> 

So by the time the FUNCALL actually calls the closure, FOO has
already returned and thus the special *SPADES* has already been
restored (correctly!) to its global value.  Capische?


-Rob

-----
Rob Warnock, 31-2-510		rpw3@sgi.com
SGI Network Engineering		<URL:http://reality.sgi.com/rpw3/>
1600 Amphitheatre Pkwy.		Phone: 650-933-1673
Mountain View, CA  94043	PP-ASEL-IA