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

defmacro within defmacro



    Date: Wed, 23 May 90 18:47 PDT
    From: Charest@AI-SUN.jpl.nasa.gov (Len Charest)

    I want to define a macro that defines another macro with some
    complex template that is best explained by example. Here goes...

    The macro I am actually writing (let's call it MACRO-MAKER) should
    have the following syntax:
	    (macro-maker name arglist)
    An example of its use looks like:
	    (macro-maker foo (bar baz ad infinitum))
	    => FOO
    The contract of macro-maker is to define a macro with the given name
    and arglist. The example above defines a macro named FOO that takes
    4 required arguments.
	    (foo 1 2 3 4)
	    => ...some result...


    What I want is to define MACRO-MAKER so that its expansion looks EXACTLY like:

    (DEFMACRO FOO (BAR BAZ AD INFINITUM)
	`(SOME-FUNCTION (LITERAL ,BAR)
			(LITERAL ,BAZ)
			(LITERAL ,AD)
			(LITERAL ,INFINITUM)))
    T

    Note the sly placement of commas within the pattern denoted by
    LITERAL. I have tried dozens of backquote-comma combinations but
    can't find the right one.  Any responses will be greatly
    appreciated.

I always have trouble with this, and finally have to punt on backquote.
This is what I refer to as the "hide the comma" problem; there is
apparently no way to defer the inner comma's evaluation in a
second-level backquote.  Here is the kind of thing I always wind up
writing:

1(defmacro macro-maker (name arglist) ;name and will become part of the inner macro's template
  `(defmacro ,name ,arglist
0     ;;assume the lists are self-quoting
     1`(some-function ,,0@1(loop for arg in arglist
0			      1collect 0`1(0list 'literal1 0,1arg)))))

0(macro-maker foo (bar baz ad nauseam))
=> (DEFMACRO FOO (BAR BAZ AD NAUSEAM)
     `(SOME-FUNCTION ,(LIST 'LITERAL BAR) ,(LIST 'LITERAL BAZ) ,(LIST 'LITERAL AD)
		     ,(LIST 'LITERAL NAUSEAM)))

(foo alpha beta gamma delta)
=> (SOME-FUNCTION (LITERAL ALPHA) (LITERAL BETA) (LITERAL GAMMA)
		  (LITERAL DELTA))

which appears to be the result you want.  I agree that it's not very
perspicuous and they're a pain in the neck to debug.

;;; Here is your desired result, for comparison:
(DEFMACRO FOO (BAR BAZ AD INFINITUM)
    `(SOME-FUNCTION (LITERAL ,BAR)
	            (LITERAL ,BAZ)
	            (LITERAL ,AD)
	            (LITERAL ,INFINITUM)))

(foo alpha beta gamma delta)
=> (SOME-FUNCTION (LITERAL ALPHA) (LITERAL BETA) (LITERAL GAMMA)
		  (LITERAL DELTA))