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

backquote



I don't understand the 3 line explanation of backquotes in backquotes
on p. 350 of CLtL.  I'd appreciate some enlightenment.  Also, I'd be
interested in whether backquote is capable of solving the problem below.
I surely don't see how to do it, but since I don't really understand
embedded backquotes I'm not sure it can't be done.

The problem:
Suppose we want to declare versions of existing functions that do type
checking, e.g., we want a protected version of (+ x y) which, if x and y
are both numbers returns their sum and otherwise returns nil.  This could
be done by the following macro:
(defmacro protected-+ (x y)
  `(let ((x ,x) (y ,y)) (and (numberp x) (numberp y) (+ x y))))
so that
(macroexpand '(protected-+ a b))
=>
(LET ((X A) (Y B))
     (AND (NUMBERP X) (NUMBERP Y) (+ X Y)))
(The let assures that each argument is evaluated only once.)

Since there are many such functions to declare, we might want a macro
to define them, e.g., 
(define-protected + (numberp x) (numberp y))
would be a reasonable way to create the macro above.

If we try to define this macro in the straight forward way we start
out like so:

(defmacro define-protected (function &rest args)
  `(defmacro ,(MAKE-PROTECTED-NAME function)
	     ,(mapcar #'cadr args)
     `(let ,(BUILD-LET-LIST args)
	(and ,@args
	     ,(BUILD-FUNCTION-CALL function args)))))

Unfortunately, it appears that BUILD-LET-LIST has to build an expression 
with more commas than backquotes, which the backquote readmacro cannot do.
Another way to look at it is that I don't see how one backquote can 
produce different backquoted expressions with varying numbers of commas.