Re: Why no SYMBOL-MACRO-FUNCTION?



Pillsy <pillsbury@xxxxxxxxx> writes:

It's not so hard to find the expansion function associated with an
ordinary macro---you just use MACRO-FUNCTION. Finding information
about the function or value associated with a symbol is similarly
straightforward. There doesn't seem to be as good a way for doing the
same with a symbol: AFAIK the best you can do is check the second
return value of macroexpand.

(defun symbol-macro-function (symbol environment)
(let* ((functions '())
(old-hook *macroexpand-hook*)
(*macroexpand-hook*
#'(lambda (function hooked-sym hooked-env)
;; There is no standard way to compare environments.
(when (eq hooked-sym symbol)
(pushnew function functions))
(funcall old-hook function hooked-sym hooked-env))))
(when (nth-value 1 (macroexpand-1 symbol environment))
(assert (= (length functions) 1) (functions)
"The symbol macro ~S seems to have ~R macro functions."
symbol (length functions))
(first functions))))

However, an implementation may use the same macro function for
all symbol macros.

MACROEXPAND-1 of SBCL 0.9.5.50 does not call *MACROEXPAND-HOOK*
when expanding a symbol macro, even though the spec clearly
requires that. I don't have a newer version available for
testing, but from the source it appears this has not been fixed.

http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/code/macroexpand.lisp?view=markup
.