From: Gerard Flynn
Subject: Understanding macros
Date: 
Message-ID: <newscache$vt8u5h$v67$1@news.tiscali.fr>
Hi,

  First I want to apologize to those who responded to my 9 november post 
for not having thanked them for their help.  I tried several times to 
repost to the thread but for some reason was unable to.  

  Now to the point of this post.

  I've been learning about macros and I'm wondering if its correct to state 
that the following two expressions are semantically equivalent (I mean same 
results and side-effects without regard to any efficiency considerations.)

(progn
  (defmacro name (arg1 arg2 ...) 
    body))

and 

(progn
  (defun name (arg1 arg2 ...)
     body)
  (eval
    (name 'arg1 'arg2 ...)))

  Where body represents the same code in each case.


  I also wonder if

(macroexpand-1 '(name a b ...))

should always return the same results as does evaluation of the above 
defun. 

  To me it seems that this is not always the case, at least if the macro 
contains errors.  

  In these cases looking at the results of the "equivalent" defun seems 
like a much easier way of debugging things than trying to interpret the 
error messages.  But since I haven't seen explicit mention of this 
possibility in tutorials on macros, I'm wondering if I'm mistaken.

  Gerard Flynn

From: Geoffrey Summerhayes
Subject: Re: Understanding macros
Date: 
Message-ID: <i8zC9.6103$kS3.638366@news20.bellglobal.com>
"Gerard Flynn" <············@libertysurf.fr> wrote in message ···························@news.tiscali.fr...
>
>   I've been learning about macros and I'm wondering if its correct to state
> that the following two expressions are semantically equivalent (I mean same
> results and side-effects without regard to any efficiency considerations.)
>
> (progn
>   (defmacro name (arg1 arg2 ...)
>     body))
>

I assume you mean

(progn
  (defmacro name (arg1 arg2 ...)
    body)
  (name arg1 arg2 ...)) ?

> and
>
> (progn
>   (defun name (arg1 arg2 ...)
>      body)
>   (eval
>     (name 'arg1 'arg2 ...)))
>
>   Where body represents the same code in each case.

So if I read this correctly, you are looking at something like this:

(progn
  (defun name (x y)
    `(+ ,x ,y))
  (eval (name 'a1 'a2)))

(progn
  (defmacro name (x y)
    `(+ ,x ,y))
  (name a1 a2))

-----------------------------------
(+ 2 2)==>4
(* 2 2)==>4
(+ 1 2 3)==>6
(* 1 2 3)==>6
...

+ is the equivalent of * !!! :-P
-----------------------------------

The equivalence you see is an illusion.

-Side-effects are not the same, try (describe 'name) after each.
-The function is called at run-time, the macro at compile-time.
-EVAL, "Evaluates form in the current dynamic environment and the null lexical environment."

Try,

(defvar *a1* 1)

(defmacro test1(x)
  `(+ ,x z))

(let ((*a1* 5)
      (z 6))
  (test1 *a1*))

(defun test2(x)
  `(+ ,x z))

(let ((*a1* 5)
      (z 6))
  (eval (test2 '*a1*)))

---
Geoff
From: Kent M Pitman
Subject: Re: Understanding macros
Date: 
Message-ID: <sfwheedz41o.fsf@shell01.TheWorld.com>
Gerard Flynn <············@libertysurf.fr> writes:

>   First I want to apologize to those who responded to my 9 november post 
> for not having thanked them for their help.  I tried several times to 
> repost to the thread but for some reason was unable to.  
> 
>   Now to the point of this post.
> 
>   I've been learning about macros and I'm wondering if its correct to state 
> that the following two expressions are semantically equivalent (I mean same 
> results and side-effects without regard to any efficiency considerations.)
> 
> (progn
>   (defmacro name (arg1 arg2 ...) 
>     body))

I assume you meant

  (progn
    (defmacro name (arg1 arg2 ...)
      body)
    (name arg1 arg2 ...))

> and 
> 
> (progn
>   (defun name (arg1 arg2 ...)
>      body)
>   (eval
>     (name 'arg1 'arg2 ...)))

No, it's more than just an issue of speed (though that issue is
significant) but macros are evaluated at compile time and your call to
the NAME function in the second example is evaluated at runtime.  This
becomes especially important speedwise if there is potentially more
than one call to the macro in question.  Further, though, it matters
WHERE the output comes out--whether it appears to the person compiling
the program or the person using the program at runtime.

You might want to see my 1980 paper
 http://world.std.com/~pitman/Papers/Special-Forms.html
which addresses a number of these issues for the older Lisp dialect Maclisp,
but effectively addresses the abstract issues that you'd want to know about
today.

>   Where body represents the same code in each case.
> 
> 
>   I also wonder if
> 
> (macroexpand-1 '(name a b ...))
> 
> should always return the same results as does evaluation of the above 
> defun. 

Not of evaluation of the DEFUN (which simply returns the name of the function
that was defined) but of the _call_ to the function that was defined.

>   To me it seems that this is not always the case, at least if the macro 
> contains errors.  

This depends a great deal on whose implementation you are using.
It's true that a lot of macro definitions run uncompiled, and so if you
get errors, you'll be [in some implementations] in the interpreter, so the
error will look like it's in a different place in your program than if you
were executing compiled code, but that's not necessarily so.  The execution
times of your program are completely different in the two cases, though,
and that has to be what decides which of the two to use.  

Remember, too, [or "learn", if you never knew it] that at compile
time, completely different global information will be available than
at execution time.  That, too, is a semantic issue.

>   In these cases looking at the results of the "equivalent" defun seems 
> like a much easier way of debugging things than trying to interpret the 
> error messages.  

If you have problem with error messages running uncompiled macros, take this
up with the individual vendor you're using. It's not a language issue.

> But since I haven't seen explicit mention of this 
> possibility in tutorials on macros, I'm wondering if I'm mistaken.

It sounds like you have a fair number of misconceptions that either more
practice, more reading, or asking some more questions will help you work
through.  Be as explicit as possible. This message of yours is too vague
because it does not offer specific transcripts of the differences you refer
to when you say "... if the macro contains errors."  Show the code and show
the error messages.  They will vary from implementation to implementation.
Also, show your actual macro. Don't just use ellipses and sample args. 
Otherwise no one can really help you and you will only frustrate them by
making them have to guess what parts you know and what you don't.  Use
of ellipses in examples should happen ONLY when you are sufficiently strong
in the language that you are already sure of what you mean, which I'm pretty
sure you are not.
From: Pascal Costanza
Subject: Re: Understanding macros
Date: 
Message-ID: <are6ig$i5f$1@newsreader2.netcologne.de>
Gerard Flynn wrote:

> 
>   I've been learning about macros and I'm wondering if its correct to state 
> that the following two expressions are semantically equivalent (I mean same 
> results and side-effects without regard to any efficiency considerations.)
> 
> (progn
>   (defmacro name (arg1 arg2 ...) 
>     body))
> 
> and 
> 
> (progn
>   (defun name (arg1 arg2 ...)
>      body)
>   (eval
>     (name 'arg1 'arg2 ...)))
> 
>   Where body represents the same code in each case.

It makes only little sense that body represents the same code in each case.

The following definitions would be equivalent to a certain degree.

(defun mult-f (arg1 arg2)
   (* arg1 arg2))

(defmacro mult-m (arg1 arg2)
   `(* ,arg1 ,arg2))

A function returns a value whereas a macro returns a program fragment. 
So in mult-f, you see code that applies the * function to both arguments 
whereas in mult-m, you see code that returns a piece of code that will 
eventually do the same. This difference is important.

Why do you embed your definitions in calls to progn? What do you want to 
achieve with the call to eval?

>   I also wonder if
> 
> (macroexpand-1 '(name a b ...))
> 
> should always return the same results as does evaluation of the above 
> defun. 

The macroexpansion of a function application always returns that 
function application. Only the macroexpansion of a macro application 
actually returns something more interesting. This is due to the same 
distinction I have mentioned above.

>   In these cases looking at the results of the "equivalent" defun seems 
> like a much easier way of debugging things than trying to interpret the 
> error messages.  But since I haven't seen explicit mention of this 
> possibility in tutorials on macros, I'm wondering if I'm mistaken.

What tutorials do you use? If you are interested in macros you should 
definitely take a look at "On Lisp" by Paul Graham 
(http://www.paulgraham.com/onlisp.html) and maybe the section on macros 
in my Lisp guide (http://www.pascalcostanza.de/lisp/guide.html).


Pascal

-- 
Given any rule, however �fundamental� or �necessary� for science, there 
are always circumstances when it is advisable not only to ignore the 
rule, but to adopt its opposite. - Paul Feyerabend
From: Gerard Flynn
Subject: Re: Understanding macros
Date: 
Message-ID: <newscache$2vdu5h$qja$1@news.tiscali.fr>
Pascal Costanza wrote:

> Gerard Flynn wrote:
> 
>> 
>>   I've been learning about macros and I'm wondering if its correct to
>>   state
>> that the following two expressions are semantically equivalent (I mean
>> same results and side-effects without regard to any efficiency
>> considerations.)
>> 
>> (progn
>>   (defmacro name (arg1 arg2 ...)
>>     body))
>> 
>> and
>> 
>> (progn
>>   (defun name (arg1 arg2 ...)
>>      body)
>>   (eval
>>     (name 'arg1 'arg2 ...)))
>> 
>>   Where body represents the same code in each case.
> 
> It makes only little sense that body represents the same code in each
> case.
> 
> The following definitions would be equivalent to a certain degree.
> 
> (defun mult-f (arg1 arg2)
>    (* arg1 arg2))
> 
> (defmacro mult-m (arg1 arg2)
>    `(* ,arg1 ,arg2))
> 
> A function returns a value whereas a macro returns a program fragment.
> So in mult-f, you see code that applies the * function to both arguments
> whereas in mult-m, you see code that returns a piece of code that will
> eventually do the same. This difference is important.
> 
> Why do you embed your definitions in calls to progn? What do you want to
> achieve with the call to eval?

  It seems I wasn't clear enough about what I was trying to say.  In fact, 
I think I forgot a step.  For the comparison to be valid, the first example 
should have been:

 (progn
   (defmacro name (arg1 arg2 ...)
     body)
    (name arg1 arg2 ...))

  To respond to your last questions first, I embedded the second example in 
progn so that it would be a single lisp expression.  I did so also for the 
first example so that my hypothetical statement would not be invalidated by 
some subtle effect of progn's I might not be aware of.

  By body, I wasn't referring to any general lisp code but only to lisp 
code which makes sense inside a defmacro (generates lisp expressions).

  As for the call to eval, I thinks it's obvious that the hypothesis is 
false if this call is omitted (well at least now that I've corrected the 
first example, before it was false anyway).  

  To be more concrete, lets take your second example of the macro named 
mult-m.  The question then is, is it or is it not true that the effects of 
evaluating your above defmacro followed by the macro call:

;; Assume that a and b are bound to values which can be multiplied.
(mult-m a b)

are exactly the same as those of evaluating the following two expressions 
in sequence:

;; Here mult-m has not been defined as a macro.

(defun mult-m (arg1 arg2)
  `(* ,arg1 ,arg2))         ;; Note that I've kept the exact same body as   
                            ;; above.
(eval 
  (mult-m 'a 'b))

  Well I see that at the least, I haven't done a very good job of stating 
things rigorously because one obvious difference between the two examples 
is that in one case name ends up defined as a macro and in the other it 
winds up defined as a function.  All I was really trying to get at was the 
possibility of using the "equivalent" defun to debug a macro by seeing 
exactly what code it generated. 

> 
>>   I also wonder if
>> 
>> (macroexpand-1 '(name a b ...))
>> 
>> should always return the same results as does evaluation of the above
>> defun.
> 
> The macroexpansion of a function application always returns that
> function application. Only the macroexpansion of a macro application
> actually returns something more interesting. This is due to the same
> distinction I have mentioned above.

  I meant to compare the macroexpand when name is defined as a macro with 
the function evaluation when name is defined as a function.

> 
>>   In these cases looking at the results of the "equivalent" defun seems
>> like a much easier way of debugging things than trying to interpret the
>> error messages.  But since I haven't seen explicit mention of this
>> possibility in tutorials on macros, I'm wondering if I'm mistaken.
> 
> What tutorials do you use? If you are interested in macros you should
> definitely take a look at "On Lisp" by Paul Graham
> (http://www.paulgraham.com/onlisp.html) and maybe the section on macros
> in my Lisp guide (http://www.pascalcostanza.de/lisp/guide.html).

  I was thinking of "On Lisp" in particular.  I'll have a look at your site.

  Gerard
From: Barry Margolin
Subject: Re: Understanding macros
Date: 
Message-ID: <mQyC9.28$0y5.790@paloalto-snr1.gtei.net>
In article <······················@news.tiscali.fr>,
Gerard Flynn  <············@libertysurf.fr> wrote:
>  I've been learning about macros and I'm wondering if its correct to state 
>that the following two expressions are semantically equivalent (I mean same 
>results and side-effects without regard to any efficiency considerations.)
>
>(progn
>  (defmacro name (arg1 arg2 ...) 
>    body))
>
>and 
>
>(progn
>  (defun name (arg1 arg2 ...)
>     body)
>  (eval
>    (name 'arg1 'arg2 ...)))
>
>  Where body represents the same code in each case.

The limited code you've provided is, indeed, equivalent (modulo the trivial
fix that has been posted in a couple of replies already).

However, if the macro expansion makes any use of lexical variables that
were bound in the caller's environment, the effects will be very different,
because EVAL executes the code in the global environment, not the local
lexical environment.  E.g.

(defun push-fun (value list-var)
  `(setq ,list-var (cons ,value ,list-var)))
(defmacro push-macro (value list-var)
  (push-fun value list-var))

(let ((some-list '(1 2 3))
      (new-element 'x))
  (push-macro new-element some-list) ; this works
  (eval (push-fun 'new-element 'some-list))) ; unbound-variable errors

If you're just trying to debug the macro in isolation, you can probably
deal with this by only using special variables.  But when the macro is
being used in production, you'll probably have to deal with it in the more
common context of lexical scopes.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.