Subject: Re: defvar affecting captured closure variables ?
From: (Rob Warnock)
Date: Sat, 06 Oct 2007 23:11:51 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
Kent M Pitman  <> wrote:
| Incidentally, ignore the advice about global lexicals.  For better or
| worse, I'm pretty sure all you want is this:
|  (define-symbol-macro foo (symbol-value 'foo))
| Don't forget to use explicit special bindings when you really mean to 
| bind these globals, since otherwise you'll get a lexical foo when you
| bind foo.

For this reason, and also to avoid unbound-variable mistakes, e.g.:

    > (define-symbol-macro foo (symbol-value 'foo))

    > foo

    Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable FOO is unbound.
       [Condition of type UNBOUND-VARIABLE]

I would suggest providing/using some binding macro for such shadowable
specials to make it clear what's going on, something like this [feel
free to suggest a shorter yet still perspicuous name]:

    > (defmacro defvar/shadowable (var &optional value (doc nil docp))
           (setf (symbol-value ',var) ,value)
           ,@(when docp
               (list `(setf (documentation ',var 'variable) ,doc)))
           (define-symbol-macro ,var (symbol-value ',var))))
    > (defvar/shadowable foo 13 "An example shadowable special")
    > (defun foo ()
	"A function which gives the global value of FOO."
    > (let ((foo 27))
        (list foo (incf foo) foo
	      (foo) (locally (declare (special foo)) (incf foo)) (foo)))
    (27 28 28 13 14 14)
    > foo

The "DEFVAR/..." part of the name will suggest that this variable
*is* still intended to be used as a special at least in some contexts
while the ".../SHADOWABLE" [or some shorter, less-awkward phrase?]
will reassure one that its binding is lexically shadowable.


p.s. I happen to think that having documentation strings
"just work" is worth a little extra effort in one's macros:

    > (describe 'foo)

    FOO is an internal symbol in the COMMON-LISP-USER package.
    It is a symbol macro with expansion: (SYMBOL-VALUE 'FOO).
    Macro documentation:
      An example shadowable special
    Function: #<Interpreted Function FOO {48A64D41}>
    Function arguments:
      There are no arguments.
    Function documentation:
      A function which gives the global value of FOO.
    Its defined argument types are:
    Its result type is:
    Its definition is:

Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607