From: metaperl.com
Subject: nested macro calls - help needed
Date: 
Message-ID: <fc175a7a-1fff-4269-a8fb-0b1c81555a2f@d4g2000prg.googlegroups.com>
Hi, I implemented the with-gensyms macro discussed in PCL without
looking. After much failure with a bottom-up attempt, I found the top-
down solution suprisingly simple:

(defmacro with-gensyms ((&rest syms) &body body)
  (let ((sympairs (loop for s in syms collect `(,s (gensym)))))
    `(let ,sympairs
       ,@body)))


One question: how could I change this line:
(let ((sympairs (loop for s in syms collect `(,s (gensym)))))

into something which abstracts creation of the pair (sym (gensym))

E.g:

(let ((sympairs (loop for s in syms collect (sympair-for s))))

From: Geoff Wozniak
Subject: Re: nested macro calls - help needed
Date: 
Message-ID: <667f635b-164c-4771-8d4d-09e3e5b91f5d@t1g2000pra.googlegroups.com>
On Dec 7, 4:21 pm, "metaperl.com" <········@gmail.com> wrote:
> One question: how could I change this line:
> (let ((sympairs (loop for s in syms collect `(,s (gensym)))))
>
> into something which abstracts creation of the pair (sym (gensym))
>
> E.g:
>
> (let ((sympairs (loop for s in syms collect (sympair-for s))))

Just move the necessary code into its own function.

(defun sympair-for (sym) `(,sym (gensym)))

This technique is very useful when writing anything that uses a nested
backquote.  I find it presents the least amount of cognitive
dissonance.
From: Daniel Weinreb
Subject: Re: nested macro calls - help needed
Date: 
Message-ID: <%pw6j.580$xd.7@trndny03>
Geoff Wozniak wrote:
> On Dec 7, 4:21 pm, "metaperl.com" <········@gmail.com> wrote:
>> One question: how could I change this line:
>> (let ((sympairs (loop for s in syms collect `(,s (gensym)))))
>>
>> into something which abstracts creation of the pair (sym (gensym))
>>
>> E.g:
>>
>> (let ((sympairs (loop for s in syms collect (sympair-for s))))
> 
> Just move the necessary code into its own function.
> 
> (defun sympair-for (sym) `(,sym (gensym)))
> 
> This technique is very useful when writing anything that uses a nested
> backquote.  I find it presents the least amount of cognitive
> dissonance.

Actually, this particular example doesn't have any
nested backquotes.  They're usually only used in
macro-defining-macros.

I have actually used triply-nested backquotes, to
make macro-defining-macro-defining-macros, although
probably only two or three times ever.  You have
to be quite careful about the distinction between
",',", ",,',", ",',,", and so on, which is rather
difficult.  Don't try this at home. :) I believe
that Alan Bawden himself is available for
consulting jobs. :)
From: Geoff Wozniak
Subject: Re: nested macro calls - help needed
Date: 
Message-ID: <71b099ac-f049-4164-8229-d5684e393d5f@i29g2000prf.googlegroups.com>
On Dec 8, 7:50 am, Daniel Weinreb <····@alum.mit.edu> wrote:
> Actually, this particular example doesn't have any
> nested backquotes.  They're usually only used in
> macro-defining-macros.
>

Yeah, I know.  I was just foreshadowing. :)

> I have actually used triply-nested backquotes, to
> make macro-defining-macro-defining-macros, although
> probably only two or three times ever.  You have
> to be quite careful about the distinction between
> ",',", ",,',", ",',,", and so on, which is rather
> difficult.  Don't try this at home. :)

My first experience with nested backquote is what led me to writing
functions for code-defining portions.  My rule of thumb is that it's
like writing: more than one comma consecutively is (probably) a
mistake.

However, I often do something like this.

`(... ,@(when test `(...)))

Not really nested, but it kind of feels like it.
From: Rainer Joswig
Subject: Re: nested macro calls - help needed
Date: 
Message-ID: <joswig-1D4C81.22444507122007@news-europe.giganews.com>
In article 
<····································@d4g2000prg.googlegroups.com>,
 "metaperl.com" <········@gmail.com> wrote:

> Hi, I implemented the with-gensyms macro discussed in PCL without
> looking. After much failure with a bottom-up attempt, I found the top-
> down solution suprisingly simple:
> 
> (defmacro with-gensyms ((&rest syms) &body body)
>   (let ((sympairs (loop for s in syms collect `(,s (gensym)))))
>     `(let ,sympairs
>        ,@body)))
> 
> 
> One question: how could I change this line:
> (let ((sympairs (loop for s in syms collect `(,s (gensym)))))
> 
> into something which abstracts creation of the pair (sym (gensym))
> 
> E.g:
> 
> (let ((sympairs (loop for s in syms collect (sympair-for s))))

You can also use local functions in the macro:

Something like this:

(defmacro with-gensyms ((&rest syms) &body body)
  (flet ((sympair-for (s)
            `(,s (gensym))))
    (let ((sympairs (loop for s in syms collect (sympair-for s))))
      `(let ,sympairs
         ,@body))))

-- 
http://lispm.dyndns.org/