Macros inside definitions

Discussion of Common Lisp
Post Reply
abvgdeika
Posts: 20
Joined: Mon Jun 06, 2011 10:59 pm

Macros inside definitions

Post by abvgdeika » Mon Jun 06, 2011 11:08 pm

Can anyone explain the following strange behaviour of macros used inside definitions:

(defmacro take (only x) `(quote ,x)) ;;; Creating very easy macro
>TAKE
(take only z) ;;; Simple test is OK
>Z
(defun same (y) y) ;;; Creating very easy function
>SAME
(same 'r) ;;;; Simple test is OK
>R
(defun mix (y x) (cons (same y) (take only x)) ) ;; Try to mix function and macro inside a next function
>MIX

(mix 'a 'b) ;;; But this test gives obviously a wrong result, it should be (A . 'B) instead!
>(A . X)
Last edited by abvgdeika on Mon Jun 06, 2011 11:56 pm, edited 1 time in total.
To understand LISP, you must first understand LISP.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Macros inside definitions

Post by ramarren » Mon Jun 06, 2011 11:21 pm

Why do you think it is strange? Being inside definition is of no significance here.

Code: Select all

(take only x)
expands to:

Code: Select all

(quote x)
And QUOTE prevents evaluation, since that is its purpose.

Remember that macros are extensions to the compiler, and hence operate during compilation phase on code fragments. The code fragments relevant to the TAKE macro in MIX definition are symbols names "only", which is discarded, and symbol named "x", which is inserted into the quote form. It has no other meaning at the time the macro is expanded.

abvgdeika
Posts: 20
Joined: Mon Jun 06, 2011 10:59 pm

Re: Macros inside definitions

Post by abvgdeika » Mon Jun 06, 2011 11:55 pm

Code: Select all

(take only x)
expands to:

Code: Select all

(quote x)

That is right. But the function mix must use the values of the assigned parameters in places of x and y, in my case the value
of assigned parameter 'b is b so the substitution to macroexpansion should give (quote b) and the result should be (A . 'B).
To understand LISP, you must first understand LISP.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Macros inside definitions

Post by ramarren » Tue Jun 07, 2011 12:05 am

Do you understand the difference between compilation and execution? Compilation and expansion of macros occurs before execution. At the time macros are expanded the are no "assigned parameters", since that is part of function evaluation, and hence occurs at execution time. Macros operate on source fragments. The source is symbol named "X", and that is what macro operates on. By the time function is evaluated and arguments are bound the expansion of the macro has already happened, and expanded to a quote form, which prevents evaluation at function execution time.

abvgdeika
Posts: 20
Joined: Mon Jun 06, 2011 10:59 pm

Re: Macros inside definitions

Post by abvgdeika » Tue Jun 07, 2011 1:58 am

I think I understood the point. It is not question of compilation and evaluation, it is a strange behavior of
the function quote. If it is inside the body of some function definition,
it does not allow function variables to go inside it. The following simple program
illustrates this:
(defun my-quote (x) (quote x))
>MY-QUOTE
(my-quote 'y)
>X
To understand LISP, you must first understand LISP.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Macros inside definitions

Post by ramarren » Tue Jun 07, 2011 3:44 am

This is elementary Common Lisp, and should have been explained by any proper learning materials. Practical Common Lisp is a good book available freely online.

QUOTE is not a function, it is a special operator. The syntax using the quote character ' is just a shorthand for it. It prevents evaluation.

Konfusius
Posts: 62
Joined: Fri Jun 10, 2011 6:38 am

Re: Macros inside definitions

Post by Konfusius » Fri Jun 10, 2011 6:47 am

abvgdeika wrote:That is right. But the function mix must use the values of the assigned parameters in places of x and y [...]
That's true for the function mix but not for the macro take because, unlike functions, macros don't evaluate their arguments. 'take' takes as an argument the form 'x' and not the value of 'x'. That's why mix returns the value of (cons (same y) (quote x)) and not the value of (cons (same y) (quote value-of-x)).

Post Reply