[Openmcl-devel] local special on symbol-macro

Tim Bradshaw tfb at tfeb.org
Thu Oct 22 01:49:26 PDT 2009

On 22 Oct 2009, at 02:42, Gary Byers wrote:
> Section (everyone's favorite section !) uses some
> unfortunate language which seems to suggest that symbol-macro
> definitions aren't subject to shadowing - "... if there is a binding  
> of
> the symbol as a symbol-macro ..." rather than something like "... if
> there is an unshadowed binding ..." -  but the dictionary entry for
> SYMBOL-MACROLET explictly discusses the notion that bindings  
> established
> by SYMBOL-MACROLET are indeed subject to shadowing amd are visible  
> whenever
> lexical bindings of the symbol would be visible (e.g., not visible  
> in cases
> like your example).  That seeming contradiction leaves a little bit of
> somewhat reasonable doubt as to what the spec actually says, but I  
> think
> that I agree with you based on a preponderance of evidence.

I think that the canonical use for SYMBOL-MACROLET gives absolutely  
persuasive evidence of what they should do:

(with-slots (x) foo
   ... x
   (locally (declare special x)
     ... x ...))

Should behave like

(let ((x ...))
   ... x ...
   (locally (declare special x)
     ... x ...))

Not do to so would be mysterious and surprising, to put it mildly.

> I don't find the "not erroring" part controversial; I read the spec as
> saying that a "bound" special declaration for a symbol-macro is  
> required
> to signal an error:
> (symbol-macrolet ((foo :foo))
>   (declare (special foo))       ; Huh ?
>   ...)

I think this case is because one needs to be able to implement CL at  
all.  If symbol macros can be declared special then how would, say,  
this be compiled:

;; file 1
(defun foo ()
   (declare (special x))

;;; file 2
(defun bar ()
   (symbol-macrolet ((x ...))
     (declare (special x))))

Now, how should I compile FOO?  I'm not sure you realistically can:  
you can't know, until you *call* it, what X is: it might be a special  
variable, or it might be a symbol macro, depending on what is up the  
stack.  So you would have to compile it at the point of call (or  
perhaps you could keep a version around for special variable and each  
possible symbol macro (as well as the source in case some other symbol  
macro is defined and you need to compile again).

I think it's pretty clear that this is mad, so symbol macros must be  

The same argument goes for top-level symbol macros.

Incidentally, Hemlock doesn't know how to indent SYMBOL-MACROLET.  The  
below fixes this, I think


Index: cocoa-ide/hemlock/src/lispmode.lisp
--- cocoa-ide/hemlock/src/lispmode.lisp (revision 13066)
+++ cocoa-ide/hemlock/src/lispmode.lisp (working copy)
@@ -857,6 +857,7 @@
  (defindent "locally" 0)
  (defindent "loop" 0)
  (defindent "macrolet" 1)
+(defindent "symbol-macrolet" 1)
  (defindent "multiple-value-bind" 2)
  (defindent "multiple-value-call" 1)
  (defindent "multiple-value-prog1" 1)

More information about the Openmcl-devel mailing list