From: jonathon
Subject: Macro evaluation sequence
Date: 
Message-ID: <1113863121.536612.60330@l41g2000cwc.googlegroups.com>
Here's one thing I'm not getting about macros.  How are they expanded
at compile time when you often do not know what the arguments are going
to be?

From: Ulrich Hobelmann
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <3cir7eF6mso4aU1@individual.net>
jonathon wrote:
> Here's one thing I'm not getting about macros.  How are they expanded
> at compile time when you often do not know what the arguments are going
> to be?
> 

You supply the arguments at compile time?

You just *write* the macro with placeholders for its arguments, 
but the macro *use* has concrete code in it.

-- 
No man is good enough to govern another man without that other's 
consent. -- Abraham Lincoln
From: Larry Clapp
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <slrnd68gok.6qm.larry@theclapp.ddts.net>
In article <·······················@l41g2000cwc.googlegroups.com>, jonathon wrote:
> Here's one thing I'm not getting about macros.  How are they
> expanded at compile time when you often do not know what the
> arguments are going to be?

Sure you do.

  (with-open-file (f "filename" :if-does-not-exist nil) 
    (when f
        (print (read-line f))))

The arguments to the WITH-OPEN-FILE macro are the following lists:

  (f "filename" :if-does-not-exist nil) 
  (when f (print (read-line f)))

The above code expands (in my Lisp[1]) into

  (let ((f (open "filename" :if-does-not-exist nil)) 
	(#:g1594 t))
    (unwind-protect
      (multiple-value-prog1 
	(progn (when f (print (read-line f))))
	(setq #:g1594 nil))
      (when f (close f :abort #:g1594))))

From this you can see that the template for with-open-file looks
(roughly speaking) something like this:

  (let ((<car-of-arg1> (open <cdr-of-arg1>))
	(<gensymed-var> t))
    (unwind-protect
      (multiple-value-prog1 
	(progn <stuff from arg2-argN>)
	(setq <gensymed-var> nil))
      (when f (close f :abort <gensymed-var>))))

All of which is available at compile time.


What macro are you trying to run that you don't know the arguments to
at compile-time?  When DO you know the arguments?

-- Larry


[1] cmucl 19a-release-20040728 + minimal debian patches
From: jonathon
Subject: Re: Macro evaluation sequence (refers to PCL)
Date: 
Message-ID: <1113877449.031124.234630@f14g2000cwb.googlegroups.com>
> All of which is available at compile time.
>
>
> What macro are you trying to run that you don't know the arguments to
> at compile-time?  When DO you know the arguments?

Hmm.  Maybe I am confusing code run from the REPL with code compiled
and run in one shot.

But here's an example of what I'm thinking about.  If you look at the
'Simple Database' chapter in PCL, the 'where' macro builds the query
clauses into a function, IIRC.

But suppose you use this database with an interactive prompt.  You ask
them for the fields they care about (artist, rating, title, etc) and
then search the database.  When is that macro evaluated with the
combination of clauses the user has just selected?
From: Peter Seibel
Subject: Re: Macro evaluation sequence (refers to PCL)
Date: 
Message-ID: <m33btnh0va.fsf@gigamonkeys.com>
"jonathon" <···········@bigfoot.com> writes:

>> All of which is available at compile time.
>>
>>
>> What macro are you trying to run that you don't know the arguments to
>> at compile-time?  When DO you know the arguments?
>
> Hmm.  Maybe I am confusing code run from the REPL with code compiled
> and run in one shot.
>
> But here's an example of what I'm thinking about.  If you look at the
> 'Simple Database' chapter in PCL, the 'where' macro builds the query
> clauses into a function, IIRC.
>
> But suppose you use this database with an interactive prompt.  You ask
> them for the fields they care about (artist, rating, title, etc) and
> then search the database.  When is that macro evaluated with the
> combination of clauses the user has just selected?

Even when used interactively, macros are processed in two phases.
First the macro is run, computing an expansion. The macro code has no
access to the values that may be associated with the symbols that
appear in the forms it is passed. Then as soon as the expansion is
computed, it is evaluated according to the normal rules, at which
points symbols in the expansion may be interpreted as references to
variables, etc.

Anyway, keep reading--the macro machinery is explained in much greater
detail in chapters 7 and 8.

-Peter

-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Costanza
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <3cit0hF6n4pcuU1@individual.net>
jonathon wrote:

> Here's one thing I'm not getting about macros.  How are they expanded
> at compile time when you often do not know what the arguments are going
> to be?

Macros transform source code into source code. So you don't see the 
arguments at all that are passed at runtime. The trick is to arrange the 
resulting code, as generated by your macro, in a way that it can still 
make sense of the received arguments.

This is a function:

(defun add (x y)
   (+ x y))

This is a macro:

(defmacro add (x y)
   `(+ ,x ,y))

If you want to see the difference between the two, evaluate (macroexpand 
'(add 5 8)), or for further insights, (macroexpand '(add 5 (* 6 7))).


Pascal

-- 
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
From: Thomas A. Russ
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <ymiwtqywq5i.fsf@sevak.isi.edu>
"jonathon" <···········@bigfoot.com> writes:

> 
> 
> Here's one thing I'm not getting about macros.  How are they expanded
> at compile time when you often do not know what the arguments are going
> to be?

There is a difference between the EXPANSION of the macro into executable
code (which happens at macroexpansion time -- for example during
compilation) and the EXECUTION of the code that results from the
expansion.  The latter happens at runtime.

For a really simple example, consider the following macro:

   (defmacro double (v) `(* 2 ,v))

A usage of this macro might appear as follows:

  (defun foo (x)
    (double (+ 2 x)))

At macro expansion time, the argument "v" to the macro DOUBLE has the
value of the list (+ 2 x).  Since this is a macro, this argument is not
evaluated.  The expansion produces the form

   (* 2 (+ 2 x))

which means that after macroexpansion, it is as if one had written the
following definition:

  (defun foo (x)
    (* 2 (+ 2 x)))

which is then compiled (if we are compiling).  Later, at run time, one
can invoke the function foo:

   (foo  3)  =>  10
   (foo -1)  =>   2

etc.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Matthew D Swank
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <pan.2005.04.19.21.16.44.98235@c.net>
> For a really simple example, consider the following macro:
> 
>    (defmacro double (v) `(* 2 ,v))
> 
> A usage of this macro might appear as follows:
> 
>   (defun foo (x)
>     (double (+ 2 x)))
> 
> At macro expansion time, the argument "v" to the macro DOUBLE has the
> value of the list (+ 2 x).  Since this is a macro, this argument is not
> evaluated.  The expansion produces the form
> 
>    (* 2 (+ 2 x))
> 
> which means that after macroexpansion, it is as if one had written the
> following definition:
> 
>   (defun foo (x)
>     (* 2 (+ 2 x)))

This also happens to correspond to normal order (lazy) evaluation of
'double' defined as a function.

Matt

-- 
"You do not really understand something unless you can
 explain it to your grandmother." — Albert Einstein.
From: Kenny Tilton
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <uFd9e.7809$n93.5090@twister.nyc.rr.com>
jonathon wrote:
> Here's one thing I'm not getting about macros.  How are they expanded
> at compile time when you often do not know what the arguments are going
> to be?
> 

Deep Thought: The arguments to a macro are the source code, which of 
course is known at macro expansion time.

ie, any expansion decisions by the macro work off the source, not 
runtime values.

kenny

-- 
Cells? Cello? Cells-Gtk?: http://www.common-lisp.net/project/cells/
Why Lisp? http://lisp.tech.coop/RtL%20Highlight%20Film

"Doctor, I wrestled with reality for forty years, and I am happy to 
state that I finally won out over it." -- Elwood P. Dowd
From: Pascal Bourguignon
Subject: Re: Macro evaluation sequence
Date: 
Message-ID: <87is2i4anx.fsf@thalassa.informatimago.com>
"jonathon" <···········@bigfoot.com> writes:

> Here's one thing I'm not getting about macros.  How are they expanded
> at compile time when you often do not know what the arguments are going
> to be?

The macro gets to decide what argument it evaluates (at runtime).
Otherwise, it can analyse the form of the argument.

(defmacro example (name value form) 
  ;; name is not evaluated.
  ;; value will be evaluated at run time.
  ;; form is analyzed at macro-expansion time.
  (let ((gvalue (gensym)))
    `(defvar ,name
       (let ((,gvalue ,value))
         ,(if (atom form)
            `(list ,gvalue ,form)
            `(list ,gvalue ,(car form)))))))


(macroexpand-1 '(example foo (+ 1 2) "Hi"))
--> (DEFVAR FOO (LET ((#:G1665 (+ 1 2))) (LIST #:G1665 "Hi"))) 

(macroexpand-1 '(example foo (/ num denum) ("Hello" "World")))
--> (DEFVAR FOO (LET ((#:G1669 (/ num denum))) (LIST #:G1669 "Hello"))) 


Another example:

(defmacro tracing (&body body)
  `(progn
     ,@(mapcan (lambda (sexp) (list `(print ',sexp *trace-output*) sexp)) body)))


(macroexpand-1 '(tracing
                 (eats *cat*   *mouse*)
                 (eats *mouse* *cheese*)
                 (eats *cow*   *grass*)))
--> (PROGN
      (PRINT '(EATS *CAT* *MOUSE*) *TRACE-OUTPUT*) 
      (EATS *CAT* *MOUSE*)
      (PRINT '(EATS *MOUSE* *CHEESE*) *TRACE-OUTPUT*) 
      (EATS *MOUSE* *CHEESE*)
      (PRINT '(EATS *COW* *GRASS*) *TRACE-OUTPUT*) 
      (EATS *COW* *GRASS*))
 

In general, you don't know what your input data will be.  You can only
analyze it and behave when you're seeing what you want.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.