From: CoffeeMug
Subject: Question about lisp macros
Date: 
Message-ID: <1107295778.802823.210510@f14g2000cwb.googlegroups.com>
I'm new to lisp (coming from an extensive C++ background) so I
apologize in advance if my questions don't make sense.

I realize that lisp macros are regular functions that are executed at
compile time. If that is the case, what happens if I bind a symbol to a
macro (not its return value, but the macro itself) and then use that
symbol to call a macro in a function? Will the macro be called at run
time as a regular function?

Also, it looks like a macro can return anything it wants. What happens
if it returns a function instead of a list? If I then use the macro in
some function, what will be the result? If a macro returns a list, it's
evident, but what about a function object?

Thanks.

From: Kenny Tilton
Subject: Re: Question about lisp macros
Date: 
Message-ID: <WDTLd.77529$ld2.26040047@twister.nyc.rr.com>
CoffeeMug wrote:
> I'm new to lisp (coming from an extensive C++ background) so I
> apologize in advance if my questions don't make sense.
> 
> I realize that lisp macros are regular functions that are executed at
> compile time. If that is the case, what happens if I bind a symbol to a
> macro (not its return value, but the macro itself) and then use that
> symbol to call a macro in a function? Will the macro be called at run
> time as a regular function?

You might want to show some simple code to make your questions easier to 
follow. Sounds tho like you mean what happens if you:

      (let ((x #'my-macro))
         (funcall x))

I am no language lawyer, but I get that same effect simply by compiling 
code: (my-macro 1 2 3) before my-macro has been declared, so a run-time 
call to my-macro gets compiled in.

At runtime I then get an error, something about trying to call a macro 
function.

> 
> Also, it looks like a macro can return anything it wants. What happens
> if it returns a function instead of a list?

Well, Lisp is still going to try to compile the value returned as if it 
were code, so whatever you return had better be compilable code.

kt

-- 
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: Peter Seibel
Subject: Re: Question about lisp macros
Date: 
Message-ID: <m3mzunj2ar.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> CoffeeMug wrote:
>> I'm new to lisp (coming from an extensive C++ background) so I
>> apologize in advance if my questions don't make sense.
>> I realize that lisp macros are regular functions that are executed
>> at
>> compile time. If that is the case, what happens if I bind a symbol to a
>> macro (not its return value, but the macro itself) and then use that
>> symbol to call a macro in a function? Will the macro be called at run
>> time as a regular function?
>
> You might want to show some simple code to make your questions easier
> to follow. Sounds tho like you mean what happens if you:
>
>       (let ((x #'my-macro))
>          (funcall x))
>
> I am no language lawyer, but I get that same effect simply by
> compiling code: (my-macro 1 2 3) before my-macro has been declared, so
> a run-time call to my-macro gets compiled in.
>
> At runtime I then get an error, something about trying to call a macro
> function.
>
>> Also, it looks like a macro can return anything it wants. What
>> happens
>> if it returns a function instead of a list?
>
> Well, Lisp is still going to try to compile the value returned as if
> it were code, so whatever you return had better be compilable code.

Also, the code returned can only contain "externalizable" objects. And
functions are not externalizable.

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kalle Olavi Niemitalo
Subject: Re: Question about lisp macros
Date: 
Message-ID: <87wttne7jx.fsf@Astalo.kon.iki.fi>
Peter Seibel <·····@javamonkey.com> writes:

> Kenny Tilton <·······@nyc.rr.com> writes:
>
>> Well, Lisp is still going to try to compile the value returned as if
>> it were code, so whatever you return had better be compilable code.
>
> Also, the code returned can only contain "externalizable" objects.

That restriction (in section 3.2.4.1) applies only if the code
will be processed by the file compiler, i.e. COMPILE-FILE, rather
than COMPILE.  Moreover, it is possible to compile a file without
processing all the forms in it.  Consider:

  (eval-when (:compile-toplevel)
    (funcall #.#'+ 2 2))

The function + is not an externalizable object, but this does
not matter, because section 3.2.3.1 says the file compiler will
"evaluate" the body of this EVAL-WHEN, rather than "process" it.
From: Andreas Thiele
Subject: Re: Question about lisp macros
Date: 
Message-ID: <ctp4hr$v6e$03$1@news.t-online.com>
"CoffeeMug" <·········@gmail.com> schrieb im Newsbeitrag
·····························@f14g2000cwb.googlegroups.com...
> I'm new to lisp (coming from an extensive C++ background) so I
> apologize in advance if my questions don't make sense.
>
> I realize that lisp macros are regular functions that are executed at
> compile time.

I'm not a guru, but I'm quite sure they are also evaluated during load-time
otherwise you could not use them in interpreted form.

> If that is the case, what happens if I bind a symbol to a
> macro (not its return value, but the macro itself) and then use that
> symbol to call a macro in a function? Will the macro be called at run
> time as a regular function?

A macro cannot be called like a function.
(funcall macro-symbol ...
is not possible

>
> Also, it looks like a macro can return anything it wants.

No - The simple thing about macros is, they just return code. The code
immediately is evaluated during load-time and I think compiled during
compile time. Thus a macro is executed before the compiler 'sees' code. It
will work on the output of the macro.

Of course the code can return a function which then is funcallable like in
the following nonsense code:

(defvar *my-funcs* nil)

(defmacro registering-defun (name (&rest args) &body body)
  `(progn
    (push (quote ,name) *my-funcs*)
    (defun ,name ,args ,@body)))

You can write

(funcall (registering-defun test2 () (princ 1)))

but you cannot execute

(funcall 'registering-defun :whatever-you-type-here-is-not-relevant)

My Lisp says:

Error: Macro or special form REGISTERING-DEFUN called as a function with
args (:WHATEVER-YOU-TYPE-HERE-IS-NOT-RELEVANT).


> What happens
> if it returns a function instead of a list? If I then use the macro in
> some function, what will be the result? If a macro returns a list, it's
> evident, but what about a function object?

The list is immediately evaluted.

>
> Thanks.
>

Andreas
From: William Bland
Subject: Re: Question about lisp macros
Date: 
Message-ID: <pan.2005.02.02.00.11.15.666569@abstractnonsense.com>
On Wed, 02 Feb 2005 00:49:15 +0100, Andreas Thiele wrote:

> A macro cannot be called like a function.
> (funcall macro-symbol ...
> is not possible

Several people (including Paul Graham I think?) have recently been
experimenting with first-class macros... I'm not sure if anything good has
come of it.

Cheers,
	Bill.
From: Jens Axel Søgaard
Subject: Re: Question about lisp macros
Date: 
Message-ID: <4202b728$0$269$edfadb0f@dread12.news.tele.dk>
William Bland wrote:

> On Wed, 02 Feb 2005 00:49:15 +0100, Andreas Thiele wrote:

>>A macro cannot be called like a function.
>>(funcall macro-symbol ...
>>is not possible

> Several people (including Paul Graham I think?) have recently been
> experimenting with first-class macros... I'm not sure if anything good has
> come of it.

E.g. Alan Bawden's "First-class Macros Have Types":

     <http://www.linearity.org/bawden/mtt/popl00.pdf>

-- 
Jens Axel Søgaard
From: drewc
Subject: Re: Question about lisp macros
Date: 
Message-ID: <J4BMd.264777$6l.51865@pd7tw2no>
William Bland wrote:
> Several people (including Paul Graham I think?) have recently been
> experimenting with first-class macros... I'm not sure if anything good has
> come of it.
> 

Arc (according to http://www.paulgraham.com/ilc03.html) currently has 
first-class macros. We've also yet to see an arc compiler ... the two 
could be related ;)

CROMA (Patrick Collison's Esat BT Young Scientist of the Year winning 
lisp dialect) has first-class macros as well, but he concludes that they 
                     are a 'bad 
idea'(http://lemonodor.com/archives/001038.html).

As Pascal's example shows, in CL "you can call a macro at run-time, only 
use MACRO-FUNCTION", but that probably isn't what you want to do. I'm no 
macro wizard, but i have trouble seeing any point to 'first-class 
macros'.. perhaps i've just yet to come across a situation where they 
would be useful.

Maybe in scheme? I've never done anything serious in scheme but the 
macro facility seems limited as they appear to be running away from 
variable capture (is this one of those save-me-from-myself things?).

drewc
From: Svein Ove Aas
Subject: Re: Question about lisp macros
Date: 
Message-ID: <ctpcum$cbp$1@services.kq.no>
Andreas Thiele wrote:
>> If that is the case, what happens if I bind a symbol to a
>> macro (not its return value, but the macro itself) and then use that
>> symbol to call a macro in a function? Will the macro be called at run
>> time as a regular function?
> 
> A macro cannot be called like a function.
> (funcall macro-symbol ...
> is not possible
> 
Well, you can get at the function with macro-function. Don't do it without
good reason, though.


>>
>> Also, it looks like a macro can return anything it wants.
> 
> No - The simple thing about macros is, they just return code. The code
> immediately is evaluated during load-time and I think compiled during
> compile time. Thus a macro is executed before the compiler 'sees' code. It
> will work on the output of the macro.
> 
A macro can return anything the compiler will compile; this can include
other things than symbols. Really just as data (to a let), though.
Its return value can be the same as for read, which is why (let ((a #
(make-hash-table))) a) works.


>> What happens
>> if it returns a function instead of a list? If I then use the macro in
>> some function, what will be the result? If a macro returns a list, it's
>> evident, but what about a function object?
> 
> The list is immediately evaluted.
> 
The function will be inserted in the code wherever the macro form was;
depending on where that is, it may or may not compile, and errors may or
may not happen at runtime.

Doing so is probably not a very good idea, however.
From: Rob Warnock
Subject: Re: Question about lisp macros
Date: 
Message-ID: <W6SdnYyDZNR6Ip3fRVn-1w@speakeasy.net>
Andreas Thiele <······@nospam.com> wrote:
+---------------
| A macro cannot be called like a function.
| (funcall macro-symbol ...
| is not possible
+---------------

Well, you *can*, but the macro function probably isn't what you'd
think it would be from looking at the DEFMACRO form. For one thing,
it always takes exactly two arguments (&whole form &environment env),
not whatever args the DEFMACRO had:

    > (defmacro foo (a b c)
	`(list ',a ,b ,(1+ c)))

    FOO
    > (macro-function 'foo)

    #<Interpreted Function "DEFMACRO FOO" {48536BA1}>
    > (describe *)

    #<Interpreted Function "DEFMACRO FOO" {48536BA1}> is function.
    Arguments:
      (A B C)
    Its defined argument types are:
      (T T)
    Its result type is:
      *
    Its definition is:
      (LAMBDA (#:WHOLE-984 #:ENV-985) (DECLARE #) (BLOCK FOO #))
    > (funcall ** '(foo bar 1 2) nil)

    (LIST 'BAR 1 3)
    > 

[Note that I gave NIL here for the environment, since I don't know
how to hand-craft a CMUCL macro environment.]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: Question about lisp macros
Date: 
Message-ID: <87brb3fe39.fsf@thalassa.informatimago.com>
"CoffeeMug" <·········@gmail.com> writes:

> I'm new to lisp (coming from an extensive C++ background) so I
> apologize in advance if my questions don't make sense.
> 
> I realize that lisp macros are regular functions that are executed at
> compile time. If that is the case, what happens if I bind a symbol to a
> macro (not its return value, but the macro itself) and then use that
> symbol to call a macro in a function? Will the macro be called at run
> time as a regular function?
> 
> Also, it looks like a macro can return anything it wants. What happens
> if it returns a function instead of a list? If I then use the macro in
> some function, what will be the result? If a macro returns a list, it's
> evident, but what about a function object?

In summary:

   - you can call a macro at run-time, only use MACRO-FUNCTION instead
     of FUNCTION (that infamous #').

        (defun some-condition () (zerop(random 2)))
        (defmacro macro-1 (arg) `(print ,arg))
        (defmacro macro-2 (arg) `#(not a list ,arg))

        (let (a-macro)
            (if (some-condition)
                (setf a-macro (macro-function 'macro-1))
                (setf a-macro (macro-function 'macro-2)))
          (funcall a-macro `(,a-macro x) 'x)) ; you must respect 
                                              ; the macro-function protocol!

      Or, you can use macroexpand:

        (let (a-macro)
            (if (some-condition)
                (setf a-macro 'macro-1)
                (setf a-macro 'macro-2))
          (macroexpand `(,a-macro x)))

      In both cases:

        --> (PRINT X)           ; sometimes
        --> #(NOT A LIST X)     ; the other times

         
    - you can return anything from a macro. Only, you have to take
      care that it will be used as expected. If you return a source
      code s-expr, you can use it from another source code s-expr. If
      it returns data, you have to call it from data.

        (defparameter x `,(macro-2 x)) 
        x --> #(NOT A LIST X)

      Of course, you should ask yourself if a function would not have
      been better here:

        (defun funct-2 (arg) `#(not a list ,arg)) ; three less characters.
        (defparameter x (funct-2 'x))             ; one less character.


And if you were asking whether you can get the code generated by the
macro at run-time executed, you can, but you'd have to use EVAL in one
way or the other, taking into account that the lexical environments
are not accesible anymore at run-time (by the compiler).  Note that
macros are normally expanded at macro-expansion time that usually
happen long before run-time. If you want to have a run-time generated
macro expanded at run-time you'll have to invoke a macro-expansion
time yourself (calling EVAL, DEFUN, or COMPILE, etc).

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

This is a signature virus.  Add me to your signature and help me to live
From: Pascal Bourguignon
Subject: Re: Question about lisp macros
Date: 
Message-ID: <873bwff65t.fsf@thalassa.informatimago.com>
Pascal Bourguignon <····@mouse-potato.com> writes:
>    - you can call a macro at run-time, only use MACRO-FUNCTION instead
>      of FUNCTION (that infamous #').
> 
>         (defun some-condition () (zerop(random 2)))
>         (defmacro macro-1 (arg) `(print ,arg))
>         (defmacro macro-2 (arg) `#(not a list ,arg))
> 
>         (let (a-macro)
>             (if (some-condition)
>                 (setf a-macro (macro-function 'macro-1))
>                 (setf a-macro (macro-function 'macro-2)))
>           (funcall a-macro `(,a-macro x) 'x)) ; you must respect 
>                                               ; the macro-function protocol!

Oops, reading Rob's answer, you'll have corrected my call: 

           (funcall a-macro `(,a-macro x) nil#|env|#)) ; I must respect 
                                        ; the macro-function protocol too!

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

In a World without Walls and Fences, 
who needs Windows and Gates?