From: Barry Margolin on
In article
<2df781d7-0eb1-484d-887d-fd960f842fd9(a)t20g2000yqa.googlegroups.com>,
Caelan Burris <caelanburris(a)gmail.com> wrote:

> Given the following definitions:
>
> (defmacro foo (x)
> (x 1 2 3))
> (defmacro bar (x)
> `(,x 1 2 3))
>
> Why does (foo if) produce an error, while (bar if) doesn't?

In Common Lisp, there are separate namespaces for functions and
variables. When a symbol is used in the function position of an
expression, its function value is used, not its variable value.

When you invoke (foo if), X's variable binding is set to IF, but not its
function binding. The expression (x 1 2 3) looks up the function
binding of X, which most likely doesn't exist.

In BAR, the backquote expression is an abbreviation for something
equivalent to (list x '1 '2 '3). In this case, X is not in the function
position, it's an argument to the LIST function. So it's evaluated as a
variable name, and evaluates to IF, so this is (list 'if '1 '2 '3).

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Tamas K Papp on
On Mon, 09 Aug 2010 10:49:18 -0400, Zach Beane wrote:

> Tamas K Papp <tkpapp(a)gmail.com> writes:
>
>> On Mon, 09 Aug 2010 07:34:20 -0700, Caelan Burris wrote:
>>
>>> Given the following definitions:
>>>
>>> (defmacro foo (x)
>>> (x 1 2 3))
>>> (defmacro bar (x)
>>> `(,x 1 2 3))
>>>
>>> Why does (foo if) produce an error, while (bar if) doesn't?
>>
>> For the same reason that the expression IF produces an error. Did you
>> read the error message?
>
> "The function X is undefined."?

My mistake, I read the first defmacro as a defun. Thanks for pointing
this out.

Tamas
From: Pascal J. Bourguignon on
Tamas K Papp <tkpapp(a)gmail.com> writes:

> On Mon, 09 Aug 2010 10:49:18 -0400, Zach Beane wrote:
>
>> Tamas K Papp <tkpapp(a)gmail.com> writes:
>>
>>> On Mon, 09 Aug 2010 07:34:20 -0700, Caelan Burris wrote:
>>>
>>>> Given the following definitions:
>>>>
>>>> (defmacro foo (x)
>>>> (x 1 2 3))
>>>> (defmacro bar (x)
>>>> `(,x 1 2 3))
>>>>
>>>> Why does (foo if) produce an error, while (bar if) doesn't?
>>>
>>> For the same reason that the expression IF produces an error. Did you
>>> read the error message?
>>
>> "The function X is undefined."?
>
> My mistake, I read the first defmacro as a defun. Thanks for pointing
> this out.

Well, macros ARE functions. But you right, I also made the mistake of
forgetting the implications of the macro functions being executed at
compilation time.

It is not enough to define the function X, you have to define it in
the compilation environment:


(eval-when (:compile-toplevel)
(defun x (a b c)
`(progn ; return a form!
(print ,a)
(print ,b)
(print ,c)
(values))))

(defmacro foo (x)
(declare (ignore x))
(x 1 2 3))


--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Caelan Burris on
On Aug 9, 8:34 pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:
> In article
> <2df781d7-0eb1-484d-887d-fd960f842...(a)t20g2000yqa.googlegroups.com>,
>  Caelan Burris <caelanbur...(a)gmail.com> wrote:
>
> > Given the following definitions:
>
> > (defmacro foo (x)
> >   (x 1 2 3))
> > (defmacro bar (x)
> >   `(,x 1 2 3))
>
> > Why does (foo if) produce an error, while (bar if) doesn't?
>
> In Common Lisp, there are separate namespaces for functions and
> variables.  When a symbol is used in the function position of an
> expression, its function value is used, not its variable value.
>
> When you invoke (foo if), X's variable binding is set to IF, but not its
> function binding.  The expression (x 1 2 3) looks up the function
> binding of X, which most likely doesn't exist.
>
> In BAR, the backquote expression is an abbreviation for something
> equivalent to (list x '1 '2 '3).  In this case, X is not in the function
> position, it's an argument to the LIST function.  So it's evaluated as a
> variable name, and evaluates to IF, so this is (list 'if '1 '2 '3).
>
> --
> Barry Margolin, bar...(a)alum.mit.edu
> Arlington, MA
> *** PLEASE post questions in newsgroups, not directly to me ***
> *** PLEASE don't copy me on replies, I'll read them in the group ***

What precisely happens to the body of a defmacro on invocation? I
suppose that's the question I'm really getting at.
From: Pascal J. Bourguignon on
Caelan Burris <caelanburris(a)gmail.com> writes:

> On Aug 9, 8:34�pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:
>> In article
>> <2df781d7-0eb1-484d-887d-fd960f842...(a)t20g2000yqa.googlegroups.com>,
>> �Caelan Burris <caelanbur...(a)gmail.com> wrote:
>>
>> > Given the following definitions:
>>
>> > (defmacro foo (x)
>> > � (x 1 2 3))
>> > (defmacro bar (x)
>> > � `(,x 1 2 3))
>>
>> > Why does (foo if) produce an error, while (bar if) doesn't?
>>
>> In Common Lisp, there are separate namespaces for functions and
>> variables. �When a symbol is used in the function position of an
>> expression, its function value is used, not its variable value.
>>
>> When you invoke (foo if), X's variable binding is set to IF, but not its
>> function binding. �The expression (x 1 2 3) looks up the function
>> binding of X, which most likely doesn't exist.
>>
>> In BAR, the backquote expression is an abbreviation for something
>> equivalent to (list x '1 '2 '3). �In this case, X is not in the function
>> position, it's an argument to the LIST function. �So it's evaluated as a
>> variable name, and evaluates to IF, so this is (list 'if '1 '2 '3).
>>
>> --
>> Barry Margolin, bar...(a)alum.mit.edu
>> Arlington, MA
>> *** PLEASE post questions in newsgroups, not directly to me ***
>> *** PLEASE don't copy me on replies, I'll read them in the group ***
>
> What precisely happens to the body of a defmacro on invocation? I
> suppose that's the question I'm really getting at.

Macros are not invocated. They are expanded by the compiler. That
is, the macro function is called to substitute the macro form by the
result of the macro function call.

(defmacro m (args) e1 ... en)

is broadly equivalent to:

(setf (macro-function 'm)
(lambda (whole &optional environment)
(destructuring-bind (macro-name args) whole
e1 ... en)))


In the compiler (and in the interpreter), there's at some place a test like:


(defun compile-form (form environment)
(cond
...

((macro-function (first form))
(compile-form (funcall (macro-function (first form)) form environment)))

...))



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