Problem calling a macro

Discussion of Common Lisp
Post Reply
lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Problem calling a macro

Post by lrodrig » Sat Jun 30, 2012 1:46 pm

Hi,

I have defined a macro that returns a closure. The basic idea is to provide a very simple OOP without using CLOS so that you can call the closure using some key parameters to get or set some attributes (free variables in the closure). The thing is that I have a function that provides a simple interface to the macro (the macro has a lot of parameters and this interface function sets some of them to default values using key parameters). This function simply calls the macro and returns the corresponding closure.

Then I can to create an "object" by calling the macro and storing the result it in a var an then I can use "funcall" on this var to set/get the "object attributes". This works well when I call the macro directly. However if I get the closure by calling the wrapper function everything seems to be ok at first (the closure is created successfully) but when I use funcall to access a specific parameter I got an error (something seems not to be evaluated during the macro expansion).

So, to summarize, A direct call to the macro works well and the same call (I mean the same call literally) inside the wrapper function doesn't. What could be causing that?

Thanks in advance,
Luis.

Kompottkin
Posts: 94
Joined: Mon Jul 21, 2008 7:26 am
Location: München, Germany
Contact:

Re: Problem calling a macro

Post by Kompottkin » Sat Jun 30, 2012 2:46 pm

Macros run (are expanded) at compile-time. Functions run at run-time. Hence, functions cannot call macros.

A macro form can appear in a function's body, of course. But the same principle applies: The macro is expanded during compilation, not when the function is called.

Assuming you have the following piece of pseudo-Lisp:

Code: Select all

(defmacro pling (arg) ...)
(defun bang (x)
  ... (pling x) ...)
(bang 10)
(bang 12)
then PLING will be called exactly once, during compilation of the DEFUN form. When the BANG forms are evaluated, the PLING macro is long gone from BANG's code (it has been expanded away), so it will never be able to see what argument you pass to BANG. It will only see the symbol X, never the 10 or the 12.

The questions you need to ask are:
  • Does your object creation operator need to be a macro (i.e., does the operator need to run at compile-time or do code transformation)? Why?
  • If yes, then why do you want the wrapper operator not to be macro? If something ought to happen at compile-time in the case of the wrapped operator, why does the same thing not need to happen at compile-time when you use the wrapper operator?
That should get you on the right track.

lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Re: Problem calling a macro

Post by lrodrig » Sun Jul 01, 2012 12:15 am

Hi,

Thank you very much for your answer. I didn't realize that the problem was caused by this simple thing (shame on me!). As you show in your example and the argument passed to the function is not sent to the macro because it has been expanded at compiling time. As expected, replacing the wrapper function with a wrapper macro works fine.

Regards,
Luis.

virex
Posts: 17
Joined: Fri Oct 28, 2011 3:41 pm

Re: Problem calling a macro

Post by virex » Tue Jul 31, 2012 4:42 am

Kompottkin wrote:Macros run (are expanded) at compile-time. Functions run at run-time. Hence, functions cannot call macros.

A macro form can appear in a function's body, of course. But the same principle applies: The macro is expanded during compilation, not when the function is called.

Assuming you have the following piece of pseudo-Lisp:

Code: Select all

(defmacro pling (arg) ...)
(defun bang (x)
  ... (pling x) ...)
(bang 10)
(bang 12)
then PLING will be called exactly once, during compilation of the DEFUN form.
Correction, it will only be called during the macro-expansion part of the compilation of the defun form, BUT! there is no guarantee on how often it will be called. Macros can be expanded multiple times, depending on the compiler and the optimization settings.

Post Reply