Subject: Re: which one of these with-gensym implementations is better?
From: (Rob Warnock)
Date: Tue, 26 Dec 2006 20:50:34 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
cmo <> wrote:
| PCL: (defmacro with-gensyms ((&rest names) &body body)
|        `(let ,(loop for n in names collect `(,n (gensym)))
|           ,@body))
| GLPS: (defmacro with-gensyms (symbols body)
|         (sublis (mapcar #'(lambda (sym)
|                             (cons sym (gensym (string sym))))
|                         symbols)
|    	          body))
| the only difference that I noticed was the fact that you need to use
| comma before variables in PCL with-gens while you do not need to do
| that in the other implementation.
| any other differences, insights.

Well, the second one has a bug, at least when being used in a Lisp2
[or LispN] such as Common Lisp -- the SUBLIS is not sensitive to
whether a symbol to be substituted in the body is in the function
or a value position, so the following happens:

    > (macroexpand-1
       '(with-gensyms (list)
	 (let ((list (list 1 2 :three)))
	   (list (length list) list))))

    (LET ((#:LIST1591 (#:LIST1591 1 2 :three)))
      (#:LIST1591 (LENGTH #:LIST1591) #:LIST1591))

Oops! That's certainly not going to fly!  ;-}

Whereas the PCL one not only requires you to be explicit about
*which* instances of the symbol(s) should be substituted, it also
assumes you will put the BODY of the WITH-GENSYMS inside its own
backquote, e.g.:

    > (macroexpand-1
       '(with-gensyms (list)
	 `(let ((,list (list 1 2 :three)))  ; Note the initial backquote!
	    (list (length ,list) ,list))))

    (LET ((LIST (GENSYM)))
      `(LET ((,LIST (LIST 1 2 :three)))
    > (eval *)

    (LET ((#:G1610 (LIST 1 2 :three)))
      (LIST (LENGTH #:G1610) #:G1610))
    > (eval *)

    (3 (1 2 :THREE))



Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607