From: Matti J Karki
Subject: Question about backquotes
Date: 
Message-ID: <cpnlci$r33$1@oravannahka.helsinki.fi>
Hi all!

I've been studying Common Lisp some time now and at the moment there
is one thing bothering me: multiple backquotes in macros. Can someone
explain me, why it's not possible to use more than one backquote at
the body of a macro?

A simple example:

    [3]> (defmacro x (a b)
           `(print ,a)
           `(print ,b)
           nil)
    X
    [4]> (x 1 2)
    NIL
    [5]> (macroexpand '(x 1 2))
    NIL ;
    T

As you can see, the macro doesn't do anything.

Another version:

    [5]> (defmacro x (a b)
           `(progn (print ,a)
                   (print ,b)
                   nil))
    X
    [6]> (x 1 2)

    1
    2
    NIL
    [7]> (macroexpand '(x 1 2))
    (PROGN (PRINT 1) (PRINT 2) NIL) ;
    T

This works as expected.

I'm sure I'm missing something trivial here, but I just can't find the
explanation from the definition of the defmacro or backquote at the
hyperspec.


Sincerely,
	Matti J. K�rki

From: Paul Dietz
Subject: Re: Question about backquotes
Date: 
Message-ID: <41BF6103.DBB4541F@motorola.com>
Matti J Karki wrote:

> I'm sure I'm missing something trivial here, but I just can't find the
> explanation from the definition of the defmacro or backquote at the
> hyperspec.

The body of a defmacro is an implicit progn.  The value returned (and
used as the macroexpansion) is the value of the last form.  The prior
forms are just executed for their side effects.

What did you expect it to return?

	Paul
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnpro$68$2@oravannahka.helsinki.fi>
Paul Dietz <············@motorola.com> wrote:
> Matti J Karki wrote:
> 
>> I'm sure I'm missing something trivial here, but I just can't find the
>> explanation from the definition of the defmacro or backquote at the
>> hyperspec.
> 
> The body of a defmacro is an implicit progn.  The value returned (and
> used as the macroexpansion) is the value of the last form.  The prior
> forms are just executed for their side effects.
> 
> What did you expect it to return?
> 

I didn't expect anything from the return values. I was wondering, why
the macro expander will erase all but the last occurrence of the
backquote expressions.

What I mean it, that when I do this:

(defmacro x ()
  `(print "The First Print")
  `(print "The Second Print"))

only the second print statement is actually executed (well, it seems
that in reality, the macroexpander just destroys the first line and
the whole macro is constructed by using the last occurrence of the
backquote expression).


Sincerely,
	Matti J. K�rki
From: Pascal Bourguignon
Subject: Re: Question about backquotes
Date: 
Message-ID: <877jnkmnvh.fsf@thalassa.informatimago.com>
Matti J Karki <·······@cs.helsinki.fi> writes:

> Paul Dietz <············@motorola.com> wrote:
> > Matti J Karki wrote:
> > 
> >> I'm sure I'm missing something trivial here, but I just can't find the
> >> explanation from the definition of the defmacro or backquote at the
> >> hyperspec.
> > 
> > The body of a defmacro is an implicit progn.  The value returned (and
> > used as the macroexpansion) is the value of the last form.  The prior
> > forms are just executed for their side effects.
> > 
> > What did you expect it to return?
> > 
> 
> I didn't expect anything from the return values. I was wondering, why
> the macro expander will erase all but the last occurrence of the
> backquote expressions.
> 
> What I mean it, that when I do this:
> 
> (defmacro x ()
>   `(print "The First Print")
>   `(print "The Second Print"))
> 
> only the second print statement is actually executed (well, it seems
> that in reality, the macroexpander just destroys the first line and
> the whole macro is constructed by using the last occurrence of the
> backquote expression).

And when you type: (macroexpand-1 '(x))
neither are executed.

Remember that backQUOTE is only but a QUOTE!
Try:

    (defmacro y ()
        (print "Executed at macro-expansion-time")
        `(print "Executed at run-time"))

    (macroexpand-1 '(y))
    (y)

Then try:

    (defun z ()
        '(print toto)
        '(print '(titi et rominet))
        (print :grandma))
    (z)

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Kenny Tilton
Subject: Re: Question about backquotes
Date: 
Message-ID: <S9Jvd.24694$Yh2.11200823@twister.nyc.rr.com>
Matti J Karki wrote:
> Hi all!
> 
> I've been studying Common Lisp some time now and at the moment there
> is one thing bothering me: multiple backquotes in macros. Can someone
> explain me, why it's not possible to use more than one backquote at
> the body of a macro?
> 
> A simple example:
> 
>     [3]> (defmacro x (a b)
>            `(print ,a)
>            `(print ,b)
>            nil)
>     X
>     [4]> (x 1 2)
>     NIL
>     [5]> (macroexpand '(x 1 2))
>     NIL ;
>     T
> 
> As you can see, the macro doesn't do anything.
> 
> Another version:
> 
>     [5]> (defmacro x (a b)
>            `(progn (print ,a)
>                    (print ,b)
>                    nil))
>     X
>     [6]> (x 1 2)
> 
>     1
>     2
>     NIL
>     [7]> (macroexpand '(x 1 2))
>     (PROGN (PRINT 1) (PRINT 2) NIL) ;
>     T
> 
> This works as expected.
> 
> I'm sure I'm missing something trivial here, but I just can't find the
> explanation from the definition of the defmacro or backquote at the
> hyperspec.

Under 3.8.10 defmacro I find:

"The expansion function accepts two arguments, a form and an 
environment. The expansion function returns a form. "

Emphasis on "a". :) You describe your first example as doing nothing. 
No, it produced three forms, throwing away the first two and returning 
the last, which was 'nil.

Your subsequent example did the trick: use PROGN to generate a multitude 
of forms. Before you worry, a form in a progn must be treated by the 
compiler as if it were at the toplevel.

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Frank Buss
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnnlu$84c$1@newsreader2.netcologne.de>
Kenny Tilton <·······@nyc.rr.com> wrote:

> "The expansion function accepts two arguments, a form and an 
> environment. The expansion function returns a form. "

and the next sentences make it more clear: "The body of the expansion 
function is specified by forms. Forms are executed in order. The value of 
the last form executed is returned as the expansion of the macro."

This means, all forms are executed, but only the result of the last form is 
returned, so this macro:

(defmacro a () (defparameter *x* 1) (print *x*))

returns 1, if calling (a).

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnoa1$sj2$2@oravannahka.helsinki.fi>
Frank Buss <··@frank-buss.de> wrote:
> 
> and the next sentences make it more clear: "The body of the expansion 
> function is specified by forms. Forms are executed in order. The value of 
> the last form executed is returned as the expansion of the macro."
> 

Thanks. Now everything is clear for me. I don't understand, how I
missed that. Sorry, if I used you guys to interpret the specification
for me.


Sincerely,
	Matti J. K�rki
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnp9d$t0q$1@oravannahka.helsinki.fi>
Frank Buss <··@frank-buss.de> wrote:
> 
> This means, all forms are executed, but only the result of the last form is 
> returned, so this macro:
> 
> (defmacro a () (defparameter *x* 1) (print *x*))
> 
> returns 1, if calling (a).
> 

Oh. For a moment I thought that I finally got this, but I just
realized that I still don't understand, why there can't be several
backquotes.

Example:

    (defmacro a () `(defparameter *x* 1) `(print *x*))

That will cause an error saying that the *x* is undefined. And _this_
is what I don't understand.


Sincerely,
	Matti J. K�rki
From: David Sletten
Subject: Re: Question about backquotes
Date: 
Message-ID: <60Kvd.18930$Ew6.11105@twister.socal.rr.com>
Matti J Karki wrote:

> Frank Buss <··@frank-buss.de> wrote:
> 
>>This means, all forms are executed, but only the result of the last form is 
>>returned, so this macro:
>>
>>(defmacro a () (defparameter *x* 1) (print *x*))
>>
>>returns 1, if calling (a).
>>
> 
> 
> Oh. For a moment I thought that I finally got this, but I just
> realized that I still don't understand, why there can't be several
> backquotes.
> 
> Example:
> 
>     (defmacro a () `(defparameter *x* 1) `(print *x*))
> 
> That will cause an error saying that the *x* is undefined. And _this_
> is what I don't understand.
> 
> 
> Sincerely,
> 	Matti J. K�rki

Once again, a _single_ value is returned as the result of the macro 
expansion. In your first example, both the DEFPARAMETER and PRINT forms 
are evaluated. The variable *X* is created, its value is printed and the 
result of PRINT (the value of *X*) is returned. This becomes the 
expansion of the macro.

In your second example you quote both forms, so neither is evaluated. 
The first is discarded and the list (PRINT *X*) becomes the expansion. 
However, since the DEFPARAMETER was not evaluated there is no variable *X*.

You should note that in this context the following are equivalent:
`(defparameter *x* 1) and '(defparameter *x* 1)

David Sletten
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnque$68$4@oravannahka.helsinki.fi>
David Sletten <·····@slytobias.com> wrote:
> 
> Once again, a _single_ value is returned as the result of the macro 
> expansion. In your first example, both the DEFPARAMETER and PRINT forms 
> are evaluated. The variable *X* is created, its value is printed and the 
> result of PRINT (the value of *X*) is returned. This becomes the 
> expansion of the macro.
> 

It took me a while but now I understand, what went wrong with my
logic. The reason was, that I was thinking the macro creation process
slightly wrong. I was associating macros too much with functions. I
didn't remember that the macro to be used is the expression returned
by the thing created by the defmacro. Very rookie error from me. Sorry
that I bothered with this kind of triviality.


> You should note that in this context the following are equivalent:
> `(defparameter *x* 1) and '(defparameter *x* 1)
> 

Yes, I'm aware of that.

Thanks!


Sincerely,
	Matti J. K�rki
From: David Sletten
Subject: Re: Question about backquotes
Date: 
Message-ID: <4nKvd.14648$nP1.11777@twister.socal.rr.com>
Matti J Karki wrote:


> It took me a while but now I understand, what went wrong with my
> logic. The reason was, that I was thinking the macro creation process
> slightly wrong. I was associating macros too much with functions. I
> didn't remember that the macro to be used is the expression returned
> by the thing created by the defmacro. Very rookie error from me. Sorry
> that I bothered with this kind of triviality.
> 
> 

If it were truly trivial, then it probably wouldn't have confused you. 
Don't be so hard on yourself. Dealing with macros requires the correct 
perspective and careful thought. It looks like you've got it now. Good luck.

David Sletten

P.S.

Have you looked at Paul Graham's book _On_Lisp_?
http://www.paulgraham.com/onlisptext.html
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnsnb$1r8$1@oravannahka.helsinki.fi>
David Sletten <·····@slytobias.com> wrote:
> 
> If it were truly trivial, then it probably wouldn't have confused you. 
> Don't be so hard on yourself. Dealing with macros requires the correct 
> perspective and careful thought. It looks like you've got it now. Good luck.
> 

Thanks!


> 
> Have you looked at Paul Graham's book _On_Lisp_?
> http://www.paulgraham.com/onlisptext.html

I have read it only partially. I have a PDF version on my computer,
but I prefer dead-tree version over the electronic version, so I
haven't yet been able to go into it more deeply. But my intention is
to either find a printed copy or spend some time at Christmas with my
laptop and try to not to strain my eyes too much.


Sincerely,
	Matti J. K�rki
From: Kenny Tilton
Subject: Re: Question about backquotes
Date: 
Message-ID: <3tNvd.24730$Yh2.11293120@twister.nyc.rr.com>
Matti J Karki wrote:

> David Sletten <·····@slytobias.com> wrote:
> 
>>Once again, a _single_ value is returned as the result of the macro 
>>expansion. In your first example, both the DEFPARAMETER and PRINT forms 
>>are evaluated. The variable *X* is created, its value is printed and the 
>>result of PRINT (the value of *X*) is returned. This becomes the 
>>expansion of the macro.
>>
> 
> 
> It took me a while but now I understand, what went wrong with my
> logic. The reason was, that I was thinking the macro creation process
> slightly wrong. I was associating macros too much with functions.

I was thinking you were associating macros /not enough/ with functions. 
:) DEFMACRO creates a macro function which gets executed at compile time 
(Duane will correct shortly the horrific error in that assertion).

It seems to me you were thinking macros were something other than 
functions, namely, that they were special things which had a certain 
splicing power relative to the code into which they were expanding. in 
which case:

(defmacro splicey ()
     `(splice this)
     `(splice that))

...would conceivably work. But once you grok that macros are just a 
special kind of function, well, consider this normal function:

(defun splice-fun ()
    (list 1 2 3)
    (list 'a 'b 'c)
    nil)

It returns nil. I trust you understand why. And so that is the deepest 
issue at play here, methinks: macros are just Lisp functions. The cool 
thing being, of course, the ways in which one can simplify user code by 
writing a function using all the power of Lisp to generate arbitrary 
code for the compiler given the minimum of user code.

kt

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Kalle Olavi Niemitalo
Subject: multiple values in DEFMACRO (was: Question about backquotes)
Date: 
Message-ID: <87llc0oxv0.fsf_-_@Astalo.kon.iki.fi>
Frank Buss <··@frank-buss.de> writes:

> and the next sentences make it more clear: "The body of the expansion 
> function is specified by forms. Forms are executed in order. The value of 
> the last form executed is returned as the expansion of the macro."

Oh.  That means CMUCL, SBCL and CLISP have a bug, unless
"expansion function" and "macro function" mean different
functions:

·····@Astalo:~$ sbcl
This is SBCL 0.8.17.20, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* ;; Define a macro where the last form returns multiple values.
  ;; The specification of DEFMACRO says the expansion function
  ;; returns "the value of the last form", which means the primary
  ;; value according to the Glossary.  So the macro function
  ;; should return just 1.
  (defmacro multi () (values 1 2 3))

MULTI
* ;; Call the macro function and see what it actually returns.
  (funcall (macro-function 'multi) '(multi) nil)

1
2
3
* ;; Verify that the same bug happens when the macro function
  ;; is called with an actual environment, rather than NIL.
  (macrolet ((quote-multi-values (&environment env)
               `',(multiple-value-list (funcall (macro-function 'multi env)
                                                '(multi) env))))
    (quote-multi-values))

(1 2 3)

The requirement to return only one value may also apply to
MACROLET, as that is specified to use "the same format used by
defmacro."
From: Pascal Bourguignon
Subject: Re: multiple values in DEFMACRO (was: Question about backquotes)
Date: 
Message-ID: <87sm68586f.fsf@thalassa.informatimago.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Frank Buss <··@frank-buss.de> writes:
> 
> > and the next sentences make it more clear: "The body of the expansion 
> > function is specified by forms. Forms are executed in order. The value of 
> > the last form executed is returned as the expansion of the macro."
> 
> Oh.  That means CMUCL, SBCL and CLISP have a bug, unless
> "expansion function" and "macro function" mean different
> functions:
> 
> ·····@Astalo:~$ sbcl
> This is SBCL 0.8.17.20, an implementation of ANSI Common Lisp.
> More information about SBCL is available at <http://www.sbcl.org/>.
> 
> SBCL is free software, provided as is, with absolutely no warranty.
> It is mostly in the public domain; some portions are provided under
> BSD-style licenses.  See the CREDITS and COPYING files in the
> distribution for more information.
> * ;; Define a macro where the last form returns multiple values.
>   ;; The specification of DEFMACRO says the expansion function
>   ;; returns "the value of the last form", which means the primary
>   ;; value according to the Glossary.  So the macro function
>   ;; should return just 1.
>   (defmacro multi () (values 1 2 3))
> 
> MULTI
> * ;; Call the macro function and see what it actually returns.
>   (funcall (macro-function 'multi) '(multi) nil)
> 
> 1
> 2
> 3
> * ;; Verify that the same bug happens when the macro function
>   ;; is called with an actual environment, rather than NIL.
>   (macrolet ((quote-multi-values (&environment env)
>                `',(multiple-value-list (funcall (macro-function 'multi env)
>                                                 '(multi) env))))
>     (quote-multi-values))
> 
> (1 2 3)
> 
> The requirement to return only one value may also apply to
> MACROLET, as that is specified to use "the same format used by
> defmacro."

You are calling the macro function directly so it's not surprizing
that you're able to capture all the returned values.

But the compiler is specified to use only one value "THE value of the
last form" from the macro. Ie. it's written as:


    (let ((gened-sexp (funcall (macro-function (car sexp) env) sexp env)))
        (compile-sexp gened-sexp))

So the other values returned by the macro are forgotten.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Kalle Olavi Niemitalo
Subject: Re: multiple values in DEFMACRO
Date: 
Message-ID: <87fz27phf9.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

> You are calling the macro function directly so it's not surprizing
> that you're able to capture all the returned values.

There are two separate steps where the primary value should be
selected in the process of macro expansion.

(1) DEFMACRO must make the expansion function return "the value
    of the last form", which means the primary value.  I was
    demonstrating that popular implementations do not conform to
    this requirement.

(2) If the expansion function does return multiple values, then I
    think the compiler, MACROEXPAND-1, and MACROEXPAND should use
    just the primary value as the expansion.  See 3.1.2.1.2.2
    "Macro Forms", which refers to "[t]he value of the expansion
    function".  This situation can be arranged with SETF of
    MACRO-FUNCTION, regardless of how DEFMACRO behaves in step 1.

    Actually, because the compiler and those functions call the
    macro function via the macroexpand hook, it suffices to bind
    *MACROEXPAND-HOOK* to something like (lambda (function form
    environment) (values (funcall function form environment) t));
    one need not even define a macro function to test this aspect
    of the compiler.

I think 3.1.2.1.2.2 makes it clear that the macro function and
the expansion function are the same function.

In my experience, it would occasionally be convenient if macro
functions defined with DEFMACRO or MACROLET could portably return
multiple values.  However, it is easy to work around the
restriction by encapsulating the values in a list; this implies
consing, but the compiler probably conses a lot more already.
From: Tim Bradshaw
Subject: Re: multiple values in DEFMACRO
Date: 
Message-ID: <ey3mzweuvhp.fsf@cley.com>
* Kalle Olavi Niemitalo wrote:
> There are two separate steps where the primary value should be
> selected in the process of macro expansion.

> (1) DEFMACRO must make the expansion function return "the value
>     of the last form", which means the primary value.  I was
>     demonstrating that popular implementations do not conform to
>     this requirement.

It's not clear to me that DEFMACRO is responsible for ensuring only
one form is returned.  I think this is up to the user.  OTOH nothing
will break if multiple values are returned.

--tim
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpno1b$sj2$1@oravannahka.helsinki.fi>
Kenny Tilton <·······@nyc.rr.com> wrote:
> 
> Under 3.8.10 defmacro I find:
> 
> "The expansion function accepts two arguments, a form and an 
> environment. The expansion function returns a form. "
> 
> Emphasis on "a". :) You describe your first example as doing nothing. 
> No, it produced three forms, throwing away the first two and returning 
> the last, which was 'nil.
> 

Oh damn. It seems that the devil is indeed in the details :) Thanks
for pointing that out. But why then the syntax definition of the
defmacro is as follows?

    Syntax:

    defmacro name lambda-list [[declaration* | documentation]] form*

    => name

Doesn't the "form*" mean that there can be any number of forms used?
I'm confused.


Sincerely,
	Matti J. K�rki
From: Kenny Tilton
Subject: Re: Question about backquotes
Date: 
Message-ID: <jXJvd.24698$Yh2.11212955@twister.nyc.rr.com>
Matti J Karki wrote:
> Kenny Tilton <·······@nyc.rr.com> wrote:
> 
>>Under 3.8.10 defmacro I find:
>>
>>"The expansion function accepts two arguments, a form and an 
>>environment. The expansion function returns a form. "
>>
>>Emphasis on "a". :) You describe your first example as doing nothing. 
>>No, it produced three forms, throwing away the first two and returning 
>>the last, which was 'nil.
>>
> 
> 
> Oh damn. It seems that the devil is indeed in the details :) Thanks
> for pointing that out. But why then the syntax definition of the
> defmacro is as follows?
> 
>     Syntax:
> 
>     defmacro name lambda-list [[declaration* | documentation]] form*
> 
>     => name
> 
> Doesn't the "form*" mean that there can be any number of forms used?
> I'm confused.

No, you are not confused. :) Yes, any number of forms can be used. Only 
one can be returned which will then be used by the compiler.

Note that you successfully wrote, compiled, and executed a defmacro with 
a body consisting of multiple forms, so the spec did not lie.

Now you might be thinking, what good is multiple forms in a macro if 
only the last will be used by the compiler? One word: side effects.

Untested:

(defmacro def-thingy ((thingy-name) &body body)
     (setf (get thingy-name 'thingy-source) body)
    `(defun ,thingy-name () ,@body))

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Pascal Bourguignon
Subject: Re: Question about backquotes
Date: 
Message-ID: <87is74msha.fsf@thalassa.informatimago.com>
Matti J Karki <·······@cs.helsinki.fi> writes:
> Oh damn. It seems that the devil is indeed in the details :) Thanks
> for pointing that out. But why then the syntax definition of the
> defmacro is as follows?
> 
>     Syntax:
> 
>     defmacro name lambda-list [[declaration* | documentation]] form*
> 
>     => name
> 
> Doesn't the "form*" mean that there can be any number of forms used?
> I'm confused.

Of course, but a macro is a function like any other: it must return
ONE form value that is used by the compiler instead of the original
form.

What you're asking is similar to expecting this:
    (defun f (x)
        (print x)
        (setf x (+ 2 x))
        (* x 3))
    (f 3) 
to return:
    3
    5
   15
instead of only:
   15

If you want it to return ALL the intermediary values, you have to
program ONE returning form with all these values:

    (defun f (x)
        (values (print x)
                (setf x (+ 2 x))
                (* x 3)))
then:
    (f 3)
will return all these values:
    3 ; 5 ; 15

BUT, the compiler will accept only ONE value from a macro function, not more.
So you MUST return only one form:

    (defmacro m (x)
        (when (numberp x) (setf x (* 2 x))) ; <-- some computation
        `(progn  (print ,x)  (terpri)))     ; <-- THE result of the macro

    (macroexpand-1 '(m 3))
    --> (PROGN (PRINT 6) (TERPRI))

    (macroexpand-1 '(m v))
    --> (PROGN (PRINT V) (TERPRI))


Of course, macro are usually more complex than just returning a form.
Otherwise, they'd would not be too useful.  That's why you can do a
lot of processing at macro-expansion time to compute the final result
of the macro.

    (defmacro cm (a1 a2 a3)
        (let (i1 i2 i3 c1 c2 c3l)
            (setf i1 (analyze-1 a1))
            (setf i2 (analyze-2 a2 a3))
            (setf i3 (analyze-3 a3))
            (do-some-check a1 i2 i3)
            (do-some-other-check a2 i1)
            (setf c1 (generate-some-code a1 i1 i2 i3))
            (setf c2 (generate-some-other-code i2 i3))
            (setf c3 (generate-yet-other-code a2 i1 i3))
            ;; and finally, generate the resulting form:
            `(tagbody
                :begin
                   ,c1 
                   (go :end)
                :inter
                   ,c2
                :end
                   (if ,c3 (go :inter)))))


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnphc$68$1@oravannahka.helsinki.fi>
Thanks, Pascal for your answer, but now this is going off-track. My
problem isn't related to multiple return values. I was wondering, why
I can't use multiple backquotes inside the macro body.

Like this:

    (defmacro a () `(defparameter *x* 1) `(print *x*))


Sincerely,
	Matti J. K�rki


Pascal Bourguignon <····@mouse-potato.com> wrote:
> Matti J Karki <·······@cs.helsinki.fi> writes:
>> Oh damn. It seems that the devil is indeed in the details :) Thanks
>> for pointing that out. But why then the syntax definition of the
>> defmacro is as follows?
>> 
>>     Syntax:
>> 
>>     defmacro name lambda-list [[declaration* | documentation]] form*
>> 
>>     => name
>> 
>> Doesn't the "form*" mean that there can be any number of forms used?
>> I'm confused.
> 
> Of course, but a macro is a function like any other: it must return
> ONE form value that is used by the compiler instead of the original
> form.
> 
> What you're asking is similar to expecting this:
>    (defun f (x)
>        (print x)
>        (setf x (+ 2 x))
>        (* x 3))
>    (f 3) 
> to return:
>    3
>    5
>   15
> instead of only:
>   15
> 
> If you want it to return ALL the intermediary values, you have to
> program ONE returning form with all these values:
> 
>    (defun f (x)
>        (values (print x)
>                (setf x (+ 2 x))
>                (* x 3)))
> then:
>    (f 3)
> will return all these values:
>    3 ; 5 ; 15
> 
> BUT, the compiler will accept only ONE value from a macro function, not more.
> So you MUST return only one form:
> 
>    (defmacro m (x)
>        (when (numberp x) (setf x (* 2 x))) ; <-- some computation
>        `(progn  (print ,x)  (terpri)))     ; <-- THE result of the macro
> 
>    (macroexpand-1 '(m 3))
>    --> (PROGN (PRINT 6) (TERPRI))
> 
>    (macroexpand-1 '(m v))
>    --> (PROGN (PRINT V) (TERPRI))
> 
> 
> Of course, macro are usually more complex than just returning a form.
> Otherwise, they'd would not be too useful.  That's why you can do a
> lot of processing at macro-expansion time to compute the final result
> of the macro.
> 
>    (defmacro cm (a1 a2 a3)
>        (let (i1 i2 i3 c1 c2 c3l)
>            (setf i1 (analyze-1 a1))
>            (setf i2 (analyze-2 a2 a3))
>            (setf i3 (analyze-3 a3))
>            (do-some-check a1 i2 i3)
>            (do-some-other-check a2 i1)
>            (setf c1 (generate-some-code a1 i1 i2 i3))
>            (setf c2 (generate-some-other-code i2 i3))
>            (setf c3 (generate-yet-other-code a2 i1 i3))
>            ;; and finally, generate the resulting form:
>            `(tagbody
>                :begin
>                   ,c1 
>                   (go :end)
>                :inter
>                   ,c2
>                :end
>                   (if ,c3 (go :inter)))))
> 
> 
From: Peter Seibel
Subject: Re: Question about backquotes
Date: 
Message-ID: <m34qiold9f.fsf@javamonkey.com>
Matti J Karki <·······@cs.helsinki.fi> writes:

> Thanks, Pascal for your answer, but now this is going off-track. My
> problem isn't related to multiple return values. I was wondering, why
> I can't use multiple backquotes inside the macro body.
>
> Like this:
>
>     (defmacro a () `(defparameter *x* 1) `(print *x*))

You can. It just isn't doing what you want. To see what expansion your
macro generates try this:

  (macroexpand-1 '(a))

When your macro is run it builds a list (defparameter *x* 1) and
throws it away. Then it builds a list (print *x*) and returns it. So
(print *x*) is taken as the expansion of (a) and compiled. The
compiler then generates an error because *x* hasn't been defined by
any code it has seen. But if you change your macro to this:

  (defmacro a () `(progn (defparameter *x* 1) (print *x*)))

the expansion will be a list (progn (defparameter *x* 1) (print *x*))
which is, presumably, what you want.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpnqbm$68$3@oravannahka.helsinki.fi>
Peter Seibel <·····@javamonkey.com> wrote:
> 
> When your macro is run it builds a list (defparameter *x* 1) and
> throws it away. Then it builds a list (print *x*) and returns it.

Aa... Now I think I got it. All along I was thinking the whole macro
creation process incorrectly. Of course. And now I understand that
other answers to my question were actually pointing to this same
obvious fact. Thanks for the explanation! Sometimes I'm a bit thick :)


Sincerely,
	Matti J. K�rki
From: Pascal Bourguignon
Subject: Re: Question about backquotes
Date: 
Message-ID: <87brcwmo3x.fsf@thalassa.informatimago.com>
Matti J Karki <·······@cs.helsinki.fi> writes:

> Thanks, Pascal for your answer, but now this is going off-track. My
> problem isn't related to multiple return values. I was wondering, why
> I can't use multiple backquotes inside the macro body.
> 
> Like this:
> 
>     (defmacro a () `(defparameter *x* 1) `(print *x*))

You seem to be linking backquote with macro result. These are
orthogonal concepts! You can use backquote anywhere!

CL-USER> (defparameter c 1)
C
CL-USER> `(a :b ,c "d")
(A :B 1 "d")

backquote is just a shortcut, syntactic suggar for combinations of
LIST, LIST* APPEND, CONC, NCONC and QUOTE:

CL-USER> (list (quote a) (quote :b) c (quote "d"))
(A :B 1 "d")


You can use backquote in functions too:

    (defun simon-says (who what how)
        `(simon says to ,who to ,what ,@how))
    
CL-USER>     (simon-says 'matti 'program '(in lisp))
(SIMON SAYS TO MATTI TO PROGRAM IN LISP)

CL-USER>     (simon-says 'matti 'eat     '(chocolate))
(SIMON SAYS TO MATTI TO EAT CHOCOLATE)

Or:

(defun deriv (expr var)
  (cond
    ((equal expr var) 1)
    ((atom expr)      0)
    ((eq '+ (car expr))
     `(+ ,(deriv (second expr) var) ,(deriv (third expr) var)))
    ((eq '* (car expr))
     `(+ (* ,(second expr) ,(deriv (third expr) var))
         (* ,(deriv (second expr) var) ,(third expr))))
    (t (error "Don't know how to derivate ~A" (car expr)))))

(DERIV '(+ (* a x x) (* b x) c) 'x)
==> (+ (+ (+ (* A (+ (* X 1) (* 1 X))) (* 0 (* X X))) (+ (* B 1) (* 0 X))) 0)

    
When you write    (defmacro a () `(defparameter *x* 1) `(print *x*))
the lisp system does something implementation-specific, but
semantically, it attaches a _function_ to the symbol A. This function
will execute these two expressions:

    `(defparameter *x* 1)
    `(print *x*)

and return the result of the last because Common Lisp specifies an
implied PROGN. Ie.
 
    (defmacro a () `(defparameter *x* 1) `(print *x*))
is equivalent to:
    (defmacro a () (progn `(defparameter *x* 1) `(print *x*)))
and PROGN is specified to return only the value of the _last_ expression.

PROGN has another property that's useful to macro writting:
expressions in a top-level PROGN are considered to be top-level too.
That means that a top-level:  (PROGN e1 e2) 
is equivalent to two top-level expressions:  e1  e2

So when you want to generate from a macro several expressions, you can
always encapsulate them in a PROGN:

    (defmacro a () `(progn (defparameter *x* 1) (print *x*)))
    (defmacro a () '(progn (defparameter *x* 1) (print *x*)))
    (defmacro a () (list 'progn '(defparameter *x* 1) '(print *x*)))

Since you don't have any comma in  you backquote expression, it's
equivalent to a simple quote. It's also equivalent (in the context of
a program souce) to building a list as above. 



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Tim Bradshaw
Subject: Re: Question about backquotes
Date: 
Message-ID: <ey34qinwskh.fsf@cley.com>
* Kenny Tilton wrote:

> Your subsequent example did the trick: use PROGN to generate a
> multitude of forms. Before you worry, a form in a progn must be
> treated by the compiler as if it were at the toplevel.

Just to nitpick: it is treated as a toplevel form if the PROGN is.

--tim
From: Kenny Tilton
Subject: Re: Question about backquotes
Date: 
Message-ID: <8d_vd.29117$ld2.12287665@twister.nyc.rr.com>
Tim Bradshaw wrote:
> * Kenny Tilton wrote:
> 
> 
>>Your subsequent example did the trick: use PROGN to generate a
>>multitude of forms. Before you worry, a form in a progn must be
>>treated by the compiler as if it were at the toplevel.
> 
> 
> Just to nitpick: 

It wouldn't be c.l.l. (Usenet?) if any nits were left unpicked. :)

> ...it is treated as a toplevel form if the PROGN is.

kt

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Matti J Karki
Subject: Re: Question about backquotes
Date: 
Message-ID: <cpokp5$cqp$1@oravannahka.helsinki.fi>
Thank you to all of you, who answered my question and had patience to
explain, what was wrong in my concepts of understanding macros! As
Kenny Tilton pointed out, I was thinking macros as some sort of
magical thing with exceptional behavior when in reality defmacro is
just another function and there is nothing special in it when we are
talking about returning results. As it was revealed, my mistake was
actually quite trivial and now when I think about this issue, it seems
so obvious, that I can't but wonder, how didn't I understand this
issue from the beginning.

Anyway, thanks for quick and insightful responses! It helped me to
sleep (it was 1 am here, when I came up with my problem and it
prevented me to get any sleep at all)!


Sincerely,
	Matti J. K�rki
From: Kenny Tilton
Subject: Re: Question about backquotes
Date: 
Message-ID: <mmRvd.24743$Yh2.11364152@twister.nyc.rr.com>
Matti J Karki wrote:

> Thank you to all of you, who answered my question and had patience to
> explain, what was wrong in my concepts of understanding macros! As
> Kenny Tilton pointed out, I was thinking macros as some sort of
> magical thing with exceptional behavior...

Come to think of it, your expectations were not unreasonable. In writing 
macros we often need to splice things much as you were hoping defmacro 
would. Since you are already in the deep end of macrology, you will 
likely be needing this soon:

(let ((ns (list 1 2 3))) `(a b c ,@ns do re mi))
=> (A B C 1 2 3 DO RE MI)

Unfortunately this @-trick does not work with the expansion /returned/ 
by the macro function, which is why it is common to see macros like:

     `(progn
         ,(make-top-level 1) ;; m-t-l generates a symbolic form
         ,(make-top-level 2)
         ,@(loop for n from 3 to 5 collecting (make-top-level n)))

kt

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Rob Warnock
Subject: Re: Question about backquotes
Date: 
Message-ID: <cqqdnY2cscR6xkfcRVn-qg@speakeasy.net>
Kenny Tilton  <·······@nyc.rr.com> wrote:
+---------------
| ...likely be needing this soon:
|   (let ((ns (list 1 2 3))) `(a b c ,@ns do re mi))
|   => (A B C 1 2 3 DO RE MI)
| Unfortunately this @-trick does not work with the expansion /returned/ 
| by the macro function, which is why it is common to see macros like:
|      `(progn
|          ,(make-top-level 1) ;; m-t-l generates a symbolic form
|          ,(make-top-level 2)
|          ,@(loop for n from 3 to 5 collecting (make-top-level n)))
+---------------

Or like this, when you need to pick and choose which pieces to
include in the expansion [and "orphaned" NILs aren't permissible]:

    `(progn
       ,@(when some-condition
	   `((some conditionally-included form)))
       ,@(when another-condition
	   `((another conditionally-included form)))
       ,@(when third-condition
	   `((several forms)
	     (need to be included)
	     (in this case))))


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607