Subject: Re: Macros that build function names
From: (Rob Warnock)
Date: Sat, 09 Aug 2003 06:37:50 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
Kent M Pitman  <> wrote:
| (Rob Warnock) writes:
| > (defmacro deflex (var val &optional (doc nil docp))    
| >   (let* ((s0 (load-time-value (symbol-name '#:*storage-for-deflex-var-)))
| Sigh. What's the advantage of this over "STORAGE-FOR-DEFLEX-VAR-" ??
| > 	     (s2 (load-time-value (symbol-name '#:*)))
| And "*" ????

It's only a visual reminder that there really *is* a normal special
variable out there that you'd better not try to bind. That is, when
someone does a DESCRIBE [at least in CMUCL] on the resulting lexical var,
they see both the documentation string and the backing variable name:

    > (deflex foo 42 "The answer to Life, The Universe, and Everything")

    > (describe 'foo)

    FOO is an internal symbol in the COMMON-LISP-USER package.
    It is a symbol macro with expansion: *STORAGE-FOR-DEFLEX-VAR-FOO*.
    Macro documentation:
      The answer to Life, The Universe, and Everything

The "*...*" in the expansion is a reminder (to me, at least) that FOO
is really still only a special under the hood. That's all.

| You don't have to use a symbol for this, btw.  A property or hash table
| should suffice and is safer. 

Yes, well, I suspect those other implementations also have the following
problem, too, that no matter how useful the illusion of "globals lexicals"
is for interactive work, they're still *not* really first-class variables.
For example, given the above, this works fine:

    > (setf foo 26) 

    > foo


but not this:

    > (setf (symbol-value 'foo) 53)

    > foo



| I usually just use a hash table or plist entry that contains a cons
| cell to store into the cdr of.  (The car can usually be the symbol
| name, just for self-doc of the cell.)

But then the run-time access of the "lexical" involves a hash table
lookup or GET overhead -- neither one negligible. Whereas the "backing
variable" approach really *is* just a variable access [after macroexpansion].

Anyway, it's not a biggy. The reason I use them at all is just so I
can type short, non-*...*'d names [e.g., "x" and "i"] at the listener
and not worry about some function's internal LET bindings accidentally
getting converted from lexical to special! That is, this:

	> (deflex x 27)
	> (load "foo.lisp")

is a *lot* safer than this:

	> (defvar x 27)
	> (load "foo.lisp")

And it works well enough for that.


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