[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

defmacro within defmacro



I'm not sure of the mathematics of it, but it wouldn't surprise me if it
were possible to prove that you can't do what you wanted under all the 
constraints that you specify (i.e., including what the intermediate expansion 
should look like) without an explicit representation of comma so that you 
can just plop it where you want. However, ...

In practice, since these situations involve multiple levels of
backquote, and since every level of backquote involves a call to EVAL,
you get two calls to EVAL to accomplish whatever end purpose you want.
So the intermediate step is not usually constrained (other than to say 
that it must be on some path back to the stated final path).  Visually:

				input form

			       /           \

        intermediate alternative 1	     intermediate alternative 2

			      \            /

			       output form

You have your mind fixed on the intermediate expression being alternative 1
above, but alternative 2 might be a better way.  There is almost never a
good reason to require the path taken be a certain way.  (In the few cases
where there are (e.g., a desire to control consing in a critical section),
you shouldn't be using backquote, which already trades off your ability to 
control exactly what's happening for expressiveness.)  So if you are willing
to admit that only the end product matters, and relax the constraint on the
intermediate code, then you can just write:

1(defmacro macro-maker (name arglist)
0  `(defmacro ,name ,arglist
     `(some-function ,@(mapcar #'(lambda (arg) `(literal ,arg))
			       `(,,@arglist)))))

It accomplishes your stated end-purpose for the macro which MACRO-MAKER defines
(although the macroexpand-1 result doesn't come out how you'd shown it):

 (macroexpand-1 '(macro-maker foo (bar baz ad infinitum)))
  (DEFMACRO FOO (BAR BAZ AD INFINITUM)
     `(SOME-FUNCTION ,@(MAPCAR #'(LAMBDA (ARG) `(LITERAL ,ARG))
			       `(,BAR ,BAZ ,AD ,INFINITUM))))

 (macro-maker foo (bar baz ad infinitum))
  FOO

 (macroexpand-1 '(foo a b c d))
  (SOME-FUNCTION (LITERAL A) (LITERAL B) (LITERAL C) (LITERAL D))

Of course, I realize that maybe all the talk about the intermediate 
expansion in your original message was not because you cared about it
but rather because that was the only way you could think of to describe
what you wanted.  That's ok.  But I think that some of the problems
that people probably ran into in thinking about your problem (and perhaps
you yourself ran into) were brought on by unconsciously being driven by
a desire to have the solution look a certain way (rather than perform
a certain way), so I wanted to make this pitfall explicit.

I hope this helps.