From: Jeffery Zhang
Subject: macro namespace
Date: 
Message-ID: <ebbvlg$cbs$1@ruby.cit.cornell.edu>
I was wondering what namespace does macros use in Common Lisp? It seems 
that it can't be the variable namespace because obviously a macro is 
not a variable, but then it can't be the function namespace either 
because a macro has no runtime presence. Can anyone briefly explain 
exactly how the macro system works? I looked at the full expansions of 
some macros, and it seems that it uses the EVAL-WHEN special form to 
eval at compile time. But the generated lisp is like nothing I've ever 
seen and I have no idea what most of it is doing.

for (defmacro f (list) (quote list))

it generated this:

(PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL)
         (EXCL::CHECK-LOCK-DEFINITIONS-COMPILE-TIME 'F 'FUNCTION
           'DEFMACRO (FBOUNDP 'F)))
       (LET* ((#:G105
               #'(LAMBDA (EXCL::**MACROARG** EXCL::..ENVIRONMENT..)
                   (DECLARE (IGNORE-IF-UNUSED EXCL::..ENVIRONMENT..))
                   (EXCL::DT-MACRO-ARGUMENT-CHECK 1 1
                     EXCL::**MACROARG** :MACRO)
                   (BLOCK F
                     (LET* ()
                       (LET* ((#:G103 (CDR EXCL::**MACROARG**))
                              (LIST (EXCL::CAR-FUSSY #:G103 'LIST))
                              (#:G104
                               (EXCL::LAMBDASCAN-MAXARGS
                                0
                                (CDR #:G103)
                                '(LIST))))
                         (DECLARE (IGNORABLE #:G104))
                         'LIST))))))
         (EXCL::.INV-MACRO-FUNCTION 'F NIL #:G105))
       (EXCL::SET-FUNC_NAME (MACRO-FUNCTION 'F) 'F)
       (EXCL::.INV-FUNC_FORMALS (FBOUNDP 'F) '(LIST))
       (EVAL-WHEN (:COMPILE-TOPLEVEL)
         (SYSTEM:AUGMENT-ENVIRONMENT
            SYSTEM:*COMPILATION-UNIT-ENVIRONMENT*
           :REUSE T
           :MACRO 'F
           :LOCATIVE (LIST #'(LAMBDA (EXCL::**MACROARG**
                                      EXCL::..ENVIRONMENT..)
                               (DECLARE
                                (IGNORE-IF-UNUSED
                                 EXCL::..ENVIRONMENT..))
                               (EXCL::DT-MACRO-ARGUMENT-CHECK
                                1
                                1
                                EXCL::**MACROARG**
                                :MACRO)
                               (BLOCK
                                F
                                (LET*
                                 ()
                                 (LET*
                                  ((#:G103 (CDR EXCL::**MACROARG**))
                                   (LIST
                                    (EXCL::CAR-FUSSY #:G103 'LIST))
                                   (#:G104
                                    (EXCL::LAMBDASCAN-MAXARGS
                                     0
                                     (CDR #:G103)
                                     '(LIST))))
                                  (DECLARE (IGNORABLE #:G104))
                                  'LIST)))))))
       (REMPROP 'F 'EXCL::%FUN-DOCUMENTATION) (RECORD-SOURCE-FILE 'F)
       'F)

-Jeffery
From: Pascal Costanza
Subject: Re: macro namespace
Date: 
Message-ID: <4jtm10F8uecjU1@individual.net>
Jeffery Zhang wrote:
> I was wondering what namespace does macros use in Common Lisp? It seems 
> that it can't be the variable namespace because obviously a macro is not 
> a variable, but then it can't be the function namespace either because a 
> macro has no runtime presence. Can anyone briefly explain exactly how 
> the macro system works? I looked at the full expansions of some macros, 
> and it seems that it uses the EVAL-WHEN special form to eval at compile 
> time. But the generated lisp is like nothing I've ever seen and I have 
> no idea what most of it is doing.

It's not correct that a macro doesn't have a runtime representation. 
First of all, it depends on whether an interpreter or a compiler is used 
to run your program. If a compiler is used, it is guaranteed that all 
macros are fully expanded at runtime, but if an intepreter is used it 
may happen that your macros are repeatedly expanded on each invocation, 
so they have to have a runtime representation in that case. Even if your 
macros are fully expanded and your code doesn't include any macro 
invocations anymore, you may still be able to refer to them in calls to 
EVAL or MACRO-FUNCTION.

Further note that macros cannot only be invoked in place of functions, 
but there are also symbol macros that can be used in place of variables. 
It is indeed the case that "regular" macros are associated with the 
function namespace and symbol macros are associated with the variable 
namespace. There is evidence for this in the ANSI CL spec - see FBOUNDP 
and SYMBOL-FUNCTION, for example, which are specified to be valid for 
macros. It's just not specified what kind of value you get when you call 
SYMBOL-FUNCTION for a macro.

It indeed makes sense that macros are in the function namespace and 
symbol macros in the variable namespace, because whenever a macro is 
lexically visible, a function of that same name cannot be lexically 
visible, and vice versa. Same for symbol macros and variables. Consider 
the following code.

(flet ((foo (...) ...))
   (macrolet ((foo (...) ...))
     ...
     (foo ...)
     ...))

It's clear that the invocation of FOO here refers to the local macro 
definition, not the outer function definition. If macros and functions 
were in different namespaces, this kind of shadowing would be cumbersome 
to implement. Again, same for symbol macros and variables, as you can 
see in the following code.

(let ((x ...))
   (symbol-macrolet ((x ...))
     ... x ...))

I hope this helps.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/