From: Kent M Pitman
Subject: Re: Define-Symbol-Macro
Date: 
Message-ID: <sfwog20gs19.fsf@world.std.com>
Matthias Hoelzl <······@informatik.uni-muenchen.de> writes:

> I think that
> 
> (define-symbol-macro foo ...)
> ... foo ...
> 
> is equivalent to
> 
> (symbol-macrolet ((foo ...))
>   ... foo ...)
> 

Yes, where the lexical scope of the latter is "for the rest of time", 
in some sense, which I guess was your intent with the "... foo ...".

A lot of the text discrepancies in ANSI CL is because the definitions 
came from disparate sources at different times, and the process of 
reconciling all the wordings was cumbersome and we just didn't have time
to finish it beyond a certain level of quality, so in a sense there are
things you might regard as "accidents of wording" still remaining.

But if I wanted to be more defensive I might say that a possible concern
was over the "... foo ..." thing above; that is, the terminology for 
the scope of DEFINE-SYMBOL-MACRO.  The problem is that there is no such
thing as a "global lexical variable" in CL, and so there was no "lexical
scope" to such a definition form; instead, one appeals to the lexical
scope of bounded forms contained within the textual space that might be
referred to.  In the case of symbol-macrolet, there is the concept of a
lexical scope, and since these things are bound in the variable namespace,
the terminology can be different without the effect being different.
But I admit it's a mess that is not done very well.  I suspect there are
passages elsewhere that clarify the processing of symbol macros, regardless
of how they are defined; but certainly the "kind of entity" asserted by a
DEFINE-SYMBOL-MACRO was not intended (at least by the editor, me) to be
different than the "kind of entity" asserted by SYMBOL-MACROLET, other than
in lexical scope.  Both are shadowable by any binding in the lexical 
namespace of variables (that is, by contained SYMBOL-MACROLETs and by
contained variable bindings), or so I feel.

It's important to understand, as an aside, that no individual is technically
capable of speaking with authority on the matter of clarification.  The
standard stands as it is, and may only be "interpreted" in any official way
by act of committee through a laborious formal process.  However, in practice,
just checking with a few committee members and verifying that implementations
agree (which I suspect they do) is usually easier.

> To put it in more concrete terms: Would the following be conforming
> behavior?
> 
> CMU Common Lisp cmucl-18c  7 September 2000 build 1020, running on falcon
> Loaded subsystems:
>     Python 1.0, target Intel x86
> * 
> * (defun foo () "foo")
> FOO
> * (defun bar () "bar")
> BAR
> * (define-symbol-macro foo 'bar)
> FOO
> * (function foo)
> #<Interpreted Function FOO {48091AC9}>
> * (funcall foo)
> "bar"
> * (funcall 'foo)
> "foo"
> * (foo)
> "foo"

These look right.

(Lispworks 4.1 has a bug where it returns the wrong value from
DEFINE-SYMBOL-MACRO.  Should return the symbol, as you show, but
returns the expansion instead.)

However, these are not the interesting cases.  The ones that would be 
affected by the question you asked are:

 ;; In spite of (DEFINE-SYMBOL-MACRO FOO ...) above, it's still true that
 ;; a local binding of FOO takes precedence.
 (let ((foo 'baz)) 
   foo)
 => BAZ   

 ;; In spite of a SYMBOL-MACROLET, the local binding of BAR takes precedence.
 (symbol-macrolet ((bar 'foo))
   (let ((bar 'baz)) bar))
 => BAZ

Hope that helps.