[Ecls-list] macro call inside function

Juan Jose Garcia-Ripoll juanjose.garciaripoll at googlemail.com
Thu Jun 4 14:21:48 UTC 2009


On Wed, Jun 3, 2009 at 3:23 AM, Yoshihara Tadafumi
<tada3 at aioros.ocn.ne.jp> wrote:
> I got an error when I try to call a macro inside a function.

Let me try to explain you the difference between a macro and a
function. A function is a piece of code that can take some arguments
an be executed. A macro is a function that transforms some template
code into a different piece of code.

When a Common Lisp implementation gets a bunch of statements, such as

(defmacro boo (x) `(cos ,x))
(+ (boo x) 2.0)

it evaluate them one after another. If the implementation is based on
a list interpreter, it will walk through the list,  finding out that
(boo x) actually referenced a macro defined before, expanding it and
evaluating the resulting list.

If the implementation, on the other hand, is based on a bytecodes
compiler, it will take the forms (+ (boo x) 2.0), analyze them,
translate them into bytecodes, and _then_ execute them. This is called
minimal compilation prior to evaluation.

Now you type this:

(defun foo (x) (boo x))

The list interpreter will simply store the function definition. Only
when the function is called it will care about what FOO means.

The bytecodes compiler and interpreter will take those statements and
process them. Since BOO has not been defined, it will assume it is a
function, which is the same assumption that would be done by COMPILE
or COMPILE-FILE, and store (BOO X) as something like "call function
BOO with argument X".

Now you type this:

(defmacro boo (x) `(+ ,x 1))

This definition has been typed _after_ the definition for BOO. The
Common Lisp implementation will not run through all places where the
name BOO has appeared and correct its interpretation that it was a
function. It does not have to. Hence

(foo 3)

now fails, because BOO is not a function, but a macro.

> Is this an expected behavior?

Yes. It is not portable to define a macro _after_ it has been used by
the first time. And here "using" means appearing in a piece of code
where it should have been interpreted as a macro.

The reason is that a Common Lisp implementation is free to choose
between a slow, code-walking interpreter, or a fast compiler that
eagerly compiles forms before executing them.

Juanjo

-- 
Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
http://juanjose.garciaripoll.googlepages.com




More information about the ecl-devel mailing list