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

backquote



I prefer the syntax (define-protected ((x fixnum) (y float)) (+ x y)).

In portable code, I would write:

 (defmacro define-protected (op bvl &body forms)
   (let ((vars  (mapcar #'car  bvl))
	 (types (mapcar #'cadr bvl)))
     `(defmacro ,(intern (format nil "PROTECTED-~A" op)) ,vars
	`(let ,(mapcar #'(lambda (var val type)
			   `(,var ,val))
		       ',vars
		       (list ,@vars))
	   (when (and ,@',(mapcar #'(lambda (var type) `(typep ,var ',type))
				  vars types))
	     ,@',forms)))))

However, in implementations (such as the Symbolics implementation) which
support ",,@" as meaning "map , across the result of the first result, I
might sometimes write:

(defmacro define-protected (op bvl &body forms)
  (let ((vars  (mapcar #'car  bvl))
	(types (mapcar #'cadr bvl)))
    `(defmacro ,(intern (format nil "PROTECTED-~A" op)) ,vars
       `((lambda ,',vars
	   (when (and ,@',(mapcar #'(lambda (var type) `(typep ,var ',type))
				  vars types))
	     ,@',forms))
	 ,,@vars))))

I have found ,,@ quite useful in practice, but I've never been clear on
whether it's portable. It had been on my list of things to raise with the
CL Cleanup committee, so thanks for giving me motivation to come up with
a useful test case.

Btw, in case your implementation doesn't support ,,@ -- here are some
test results for comparison:

 (macroexpand-1
    '(define-protected + ((x fixnum) (y float)) (+ x y)))

 => (DEFMACRO PROTECTED-+ (X Y)
      `((LAMBDA (X Y)
	  (WHEN (AND (TYPEP X 'FIXNUM)
		     (TYPEP Y 'FLOAT))
	    (+ X Y)))
	,X ,Y))