Hello,
i have a problem with macro expansion. The Lisp-System is a branch of KCL.
I want to compile a file in which all macros, used in a function, should
be expanded at load time and not at compile time.
Suppose I have two packages (in two files): frank1 and frank2. frank1
defines a macro, which is used in frank2:
(in-package :frank1)
(defmacro banane ()
(print 'x))
(in-package :frank2)
(defun gox ()
(print (frank1::banane)))
Now I load and compile them. If I run gox I get the symbol x printed. If
I now change the macro in frank1 to
(defmacro banane ()
(print 'y))
and load frank2, it should print y.
I tried with (eval-whan (load) ...) but no success. Only solution I can
come up with so far is using (read-from-string), but I do not like that.
Can anybody give me a hint?
Frank Roland <·········@frank-roland.de> wrote in message news:<···············@news.t-online.com>...
> Hello,
>
> i have a problem with macro expansion. The Lisp-System is a branch of KCL.
>
> I want to compile a file in which all macros, used in a function, should
> be expanded at load time and not at compile time.
That doesn't make sense at all. Macros must be expanded before
compilation, because they work with the lists and atoms that make up
the program source code. Once you compile, the source code is gone,
replaced by object code.
> Suppose I have two packages (in two files): frank1 and frank2. frank1
> defines a macro, which is used in frank2:
> (in-package :frank1)
> (defmacro banane ()
> (print 'x))
You mean '(print 'x) right? Otherwise you are printing 'x at
macro-expansion time; your macro is not producing the form (print 'x)
to be substituted into the program text.
> (in-package :frank2)
> (defun gox ()
> (print (frank1::banane)))
>
> Now I load and compile them. If I run gox I get the symbol x printed. If
> I now change the macro in frank1 to
> (defmacro banane ()
> (print 'y))
> and load frank2, it should print y.
Your expectation is unrealistic. The module frank1 supplies some
macros to the compilation of frank2. Once frank2 is compiled, changes
to frank1 have no effect on the compiled image of frank2. But that
compiled image is, at that point, out of date with respect to the
macro module.
When you change a macro, you must recompile all modules which are
dependent on the macro, and then reload them.
So you must recompile frank2, not just reload it; that compilation
will pick up the new version of the macro and compile a new version of
the GOX function using the new frank1::banane macro. Without that
compilation, you are just loading the same old image.
In article <···············@news.t-online.com>,
Frank Roland <·········@frank-roland.de> wrote:
>Hello,
>
>i have a problem with macro expansion. The Lisp-System is a branch of KCL.
>
>I want to compile a file in which all macros, used in a function, should
>be expanded at load time and not at compile time.
That's not generally possible. The compiler is *required* to expand
macros. When it sees a list being used as an expression, it must determine
if its car is the name of a function, macro, or special operator. If it's
a special operator it does whatever special processing is required for the
form; if it's a macro, it expands the macro; and in all other cases, it
assumes it's a function and generates code to call the function.
>Suppose I have two packages (in two files): frank1 and frank2. frank1
>defines a macro, which is used in frank2:
>(in-package :frank1)
>(defmacro banane ()
> (print 'x))
>
>(in-package :frank2)
>(defun gox ()
> (print (frank1::banane)))
>
>Now I load and compile them. If I run gox I get the symbol x printed. If
>I now change the macro in frank1 to
>(defmacro banane ()
> (print 'y))
>and load frank2, it should print y.
>
>I tried with (eval-whan (load) ...) but no success. Only solution I can
>come up with so far is using (read-from-string), but I do not like that.
The only solution I can think of is:
(defun gox ()
(eval '(frank1::banane)))
This will expand the macro each time the function is called.
Maybe if you explain *why* you want to do this we can suggest a better
solution.
--
Barry Margolin, ······@genuity.com
Genuity Managed Services, 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.
Barry Margolin wrote:
> In article <···············@news.t-online.com>,
> Frank Roland <·········@frank-roland.de> wrote:
>
>>Hello,
>>
>>i have a problem with macro expansion. The Lisp-System is a branch of KCL.
>>
>>I want to compile a file in which all macros, used in a function, should
>>be expanded at load time and not at compile time.
>
>
> That's not generally possible. The compiler is *required* to expand
> macros. When it sees a list being used as an expression, it must determine
> if its car is the name of a function, macro, or special operator. If it's
> a special operator it does whatever special processing is required for the
> form; if it's a macro, it expands the macro; and in all other cases, it
> assumes it's a function and generates code to call the function.
>
>
>>Suppose I have two packages (in two files): frank1 and frank2. frank1
>>defines a macro, which is used in frank2:
>>(in-package :frank1)
>>(defmacro banane ()
>> (print 'x))
>>
>>(in-package :frank2)
>>(defun gox ()
>> (print (frank1::banane)))
>>
>>Now I load and compile them. If I run gox I get the symbol x printed. If
>>I now change the macro in frank1 to
>>(defmacro banane ()
>> (print 'y))
>>and load frank2, it should print y.
>>
>>I tried with (eval-whan (load) ...) but no success. Only solution I can
>>come up with so far is using (read-from-string), but I do not like that.
>
>
> The only solution I can think of is:
>
> (defun gox ()
> (eval '(frank1::banane)))
Hey, thanks. This could really work (it did for a small example, but
here at home I have a completly different lisp comiler).
>
> This will expand the macro each time the function is called.
>
> Maybe if you explain *why* you want to do this we can suggest a better
> solution.
>
I have to use a macro from another package (defines GUI dialogs).
It turned out that a function (in a third package), called by code
generated by the macro, changed its number of arguments. This yields an
fatal error if dialog is opend.
So either your suggestion works or I will use read-from-string...
Frank Roland <·········@frank-roland.de> writes:
> Hello,
>
> i have a problem with macro expansion. The Lisp-System is a branch of KCL.
>
> I want to compile a file in which all macros, used in a function,
> should be expanded at load time and not at compile time.
Then you do not want to compile the file.
3.2.2.2 Minimal Compilation
Minimal compilation is defined as follows:
* [...]
* All macro and symbol macro calls appearing in the source code
being compiled are expanded at compile time in such a way that
they will not be expanded again at run time.
You can load code uncompiled, and it will expand the macros at runtime
(at load time in some implementations, but during execution in others).
You can even invoke the compiler on the source file at load time and
then load the freshly compiled code so that it expands only once
during the setup time and not later during execution.
- - - - -
> Suppose I have two packages (in two files): frank1 and frank2. frank1
> defines a macro, which is used in frank2:
> (in-package :frank1)
> (defmacro banane ()
> (print 'x))
>
> (in-package :frank2)
> (defun gox ()
> (print (frank1::banane)))
>
> Now I load and compile them. If I run gox I get the symbol x
> printed. If I now change the macro in frank1 to
> (defmacro banane ()
> (print 'y))
> and load frank2, it should print y.
>
> I tried with (eval-whan (load) ...) but no success. Only solution I
> can come up with so far is using (read-from-string), but I do not like
> that.
>
>
> Can anybody give me a hint?
HINTS:
1. You are probably just totally using macros wrong in the first place.
Although you can, with some work, force what you asked for to happen,
you will be much better off revising your understanding of when macros
are appropriate and for what.
2. This is a terrible example, not just because the defmacro is more
concerned with what it prints than what it returns, but also because
the example is so contrived that there's no hope of suggesting an
alternative.