Subject: Re: lambda-returning defmacro, capture
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 17 Dec 2006 06:39:02 -0600
Newsgroups: comp.lang.lisp
Message-ID: <3qKdnRF8hLf7pxjYnZ2dnUVZ_tijnZ2d@speakeasy.net>
<danmbox@gmail.com> wrote:
+---------------
| Rob Warnock wrote:
| > p.p.s. Note that there's a long-standing problem in CMUCL with
| > DEFINE-SYMBOL-MACRO expansion, that fails no matter which of
| > the above you use. ...
| 
| Thanks Rob. It sounds like symbol macros aren't settled and are
| subject to bugs in some implementations.
+---------------

Symbol macros *are* "settled": they're in ANSI Common Lisp:

    http://www.alu.org/HyperSpec/Body/mac_define-symbol-macro.html
    http://www.alu.org/HyperSpec/Body/speope_symbol-macrolet.html

Remember, Common Lisp is defined by the ANSI standard, *not* by
any particular implementation, and *especially* not by the bugs
and/or standards-conformance issues of any particular implementation.

The bug in CMUCL is understood, and a fix is in progress. There is
no reason to avoid symbol macros unless you both must use CMUCL
*and* cannot wait for a fix. [If you want to fix it yourself, the
problem is in "src/code/eval.lisp", in the function MACROEXPAND-1.
If you compare the first COND there with the similar one in the
MACRO-FUNCTION function just above, the fix may be obvious.]
If you're using any other implementation of CL, it probably
works fine.

+---------------
| Then there's the proliferation of multiple deflex macros...
+---------------

This statement verges on FUD. Since DEFLEX is not part of the
standard, of *course* there are multiple versions. But that's
no different than any other useful abstraction that is not part
of the standard, such as socket libraries.

+---------------
| ...each with its own problems.
+---------------

As far as I know, there are two main approaches which work just
fine across implementations: One expands FOO to #.(MANGLE-NAME 'FOO)
[for some choice of #'MANGLE-NAME) and uses DEFPARAMETER to set
the initial value of #.(MANGLE-NAME 'FOO); the other expands FOO
to (SYMBOL-VALUE 'FOO) and uses the (LOCALLY (SPECIAL FOO) (SETF
(SYMBOL-VALUE 'FOO) ...)) hack to set the initial value. I personally
have always used the first, because on the implementation I use most
[CMUCL] it generates slightly better code than the second. But YMMV.

There was *one* erroneous approach [expand FOO to #:FOO] which I
mistakenly presented in an earlier posting because I forgot that
it breaks separate compilation. My apologies for any confusion
generated by that.

+---------------
| Also, if there are multiple source files, are the backing variables
| going to be the same?
+---------------

For both of the above working approaches, yes. But to make it truly
useful in that case you will need a separate version of the macro
[definition of which is left as an exercise for the reader] that
doesn't initialize the variable, but only defines the symbol macro.
I myself have only ever had to do this once, but it sounds like your
application might need it more.


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607