From: nsr
Subject: nested backquote confusion
Date: 
Message-ID: <1114564806.766709.31020@g14g2000cwa.googlegroups.com>
I'm a bit confused regarding the rules of processing nested backquote
(reading the appendix of CLtL2 further confuses me, it's too
advance...)

In the examples below, only the "," that is at the same nested level of
the outer "`" is evaluated. The preceding "," is left as is.

That's how I got ",code1 ,code2" (or ",(code1 code2)" in the 2nd
example).
However, why there's no preceding "," for ",,@body" ?

So instead of "(x y z)" I'm expecting ",(x y z)".

I know that nested backquote is not recommended for most situations
(I've read Clementson's example), but it helps to understand the rules
in code reading.

Any help would be appreciated.
-nsr


(defmacro a-list (&body body)
  (let ((localbody '(code1 code2)))
	``(a ,,@localbody ,,@body)))

> (a-list '(x y z))
`(A ,CODE1 ,CODE2 (X Y Z))

(defmacro b-list (&body body)
  (let ((b 'b)
	(localbody '(code1 code2)))
	``(,,b ,,localbody ,,@body)))

> (B-LIST '(x y z))
`(,B ,(CODE1 CODE2) (X Y Z))

From: Pascal Bourguignon
Subject: Re: nested backquote confusion
Date: 
Message-ID: <871x8womyw.fsf@thalassa.informatimago.com>
"nsr" <········@gmail.com> writes:

> I'm a bit confused regarding the rules of processing nested backquote
> (reading the appendix of CLtL2 further confuses me, it's too
> advance...)
>
> In the examples below, only the "," that is at the same nested level of
> the outer "`" is evaluated. The preceding "," is left as is.
>
> That's how I got ",code1 ,code2" (or ",(code1 code2)" in the 2nd
> example).
> However, why there's no preceding "," for ",,@body" ?
>
> So instead of "(x y z)" I'm expecting ",(x y z)".
>
> I know that nested backquote is not recommended for most situations
> (I've read Clementson's example), but it helps to understand the rules
> in code reading.
>
> Any help would be appreciated.
> -nsr
>
>
> (defmacro a-list (&body body)
>   (let ((localbody '(code1 code2)))
> 	``(a ,,@localbody ,,@body)))
>
>> (a-list '(x y z))
> `(A ,CODE1 ,CODE2 (X Y Z))
>
> (defmacro b-list (&body body)
>   (let ((b 'b)
> 	(localbody '(code1 code2)))
> 	``(,,b ,,localbody ,,@body)))
>
>> (B-LIST '(x y z))
> `(,B ,(CODE1 CODE2) (X Y Z))

What implementation are you using?
With clisp:

[10]> (defmacro a-list (&body body)
  (let ((localbody '(code1 code2)))
	``(a ,,@localbody ,,@body)))

A-LIST
[11]> (macroexpand-1 '(a-list '(x y z)))
(LIST 'A CODE1 CODE2 '(X Y Z)) ;
T
[12]> (defmacro b-list (&body body)
  (let ((b 'b)
	(localbody '(code1 code2)))
	``(,,b ,,localbody ,,@body)))
B-LIST
[13]> (macroexpand-1 '(B-LIST '(x y z)))
(LIST B (CODE1 CODE2) '(X Y Z)) ;
T


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

There is no worse tyranny than to force a man to pay for what he does not
want merely because you think it would be good for him. -- Robert Heinlein
From: nsr
Subject: Re: nested backquote confusion
Date: 
Message-ID: <1114583267.735529.148210@z14g2000cwz.googlegroups.com>
Yes I noticed that clisp behaves differently.

Lispworks, cmucl & sbcl all expand to the form that I described.

Corman's expansion is same as clisp's.

> (macroexpand '(a-list '(x y z)))
(CONS 'A (APPEND (LIST CODE1 CODE2) (LIST '(X Y Z))))
> (macroexpand '(B-LIST '(x y z)))
(LIST B (CODE1 CODE2) '(X Y Z))

I believe Lispworks' expansion is correct, but I just don't understand
why there is no preceding "," after the ,,@body substitution.

I don't ACL or MCL installed but I think the result will agree with
Lispworks'.

-nsr
From: Timothy Moore
Subject: Re: nested backquote confusion
Date: 
Message-ID: <wdrbr80r6lw.fsf@cleo.labri.fr>
"nsr" <········@gmail.com> writes:

> I'm a bit confused regarding the rules of processing nested backquote
> (reading the appendix of CLtL2 further confuses me, it's too
> advance...)
> 
> In the examples below, only the "," that is at the same nested level of
> the outer "`" is evaluated. The preceding "," is left as is.
> 
> That's how I got ",code1 ,code2" (or ",(code1 code2)" in the 2nd
> example).
> However, why there's no preceding "," for ",,@body" ?
> 
> So instead of "(x y z)" I'm expecting ",(x y z)".

,,@body can be confusing because the result of the splice is several
forms, embedded in-line in the containing list. So, to what should the
outer comma be "applied"? It turns out that the outer comma is
distributed over all the elements of the results of the splice. In
your example the value of body is ('(x y z)). So, after the first
backquote is processed, the result list contains, in effect,
 (... ,'(x y z)). Of course that's how ,CODE1 ,CODE2 appear in the
result as well.
> I know that nested backquote is not recommended for most situations
> (I've read Clementson's example), but it helps to understand the rules
> in code reading.

I don't agree. Nested backquote is complicated, but in the domain of
macro-defining macros I find them clearer than creating the result "by
hand."

Tim

> (defmacro a-list (&body body)
>   (let ((localbody '(code1 code2)))
> 	``(a ,,@localbody ,,@body)))
> 
> > (a-list '(x y z))
> `(A ,CODE1 ,CODE2 (X Y Z))
> 
> (defmacro b-list (&body body)
>   (let ((b 'b)
> 	(localbody '(code1 code2)))
> 	``(,,b ,,localbody ,,@body)))
> 
> > (B-LIST '(x y z))
> `(,B ,(CODE1 CODE2) (X Y Z))
From: Kent M Pitman
Subject: Re: nested backquote confusion
Date: 
Message-ID: <u7jio4hev.fsf@nhplace.com>
Timothy Moore <·····@cleo.labri.fr> writes:

> "nsr" <········@gmail.com> writes:
> 
> > I'm a bit confused regarding the rules of processing nested backquote
> > (reading the appendix of CLtL2 further confuses me, it's too
> > advance...)
> > 
> > In the examples below, only the "," that is at the same nested level of
> > the outer "`" is evaluated. The preceding "," is left as is.
> > 
> > That's how I got ",code1 ,code2" (or ",(code1 code2)" in the 2nd
> > example).
> > However, why there's no preceding "," for ",,@body" ?
> > 
> > So instead of "(x y z)" I'm expecting ",(x y z)".
> 
> ,,@body can be confusing because the result of the splice is several
> forms, embedded in-line in the containing list. So, to what should the
> outer comma be "applied"? It turns out that the outer comma is
> distributed over all the elements of the results of the splice. 

I agree.

> In your example the value of body is ('(x y z)). So, after the first
> backquote is processed, the result list contains, in effect,
>  (... ,'(x y z)). Of course that's how ,CODE1 ,CODE2 appear in the
> result as well.
> > I know that nested backquote is not recommended for most situations
> > (I've read Clementson's example), but it helps to understand the rules
> > in code reading.
> 
> I don't agree. Nested backquote is complicated, but in the domain of
> macro-defining macros I find them clearer than creating the result "by
> hand."

I agree again.

I will note as an addendum here that there is usually a way, by
cascading named macros, one for each level of backquoting, to avoid it.

But just as #'(lambda ...) can always be avoided by writing named functions,
so too it's often just useful to doubly (or even triply) nest backquotes.
For as often as it comes up.  Which is very rarely.  So when I say "often"
I mean "often as a proportion of the set of cases where it turns out to 
matter...", not "gee, I find I write double and triple backquotes every day".