From: Michele Lamarca
Subject: A simple(?) macro
Date: 
Message-ID: <1127719345.976586.315180@f14g2000cwb.googlegroups.com>
Hello everyone,
I'm a Lisp novice, so I'm experimenting with simple macros.

CL-USER> (setf alist '(a b))
(A B)
CL-USER> `(defstruct astruct ,@alist)
(DEFSTRUCT ASTRUCT A B)

Ok, that's the result I expect.

CL-USER> (defmacro def-astruct (lst)
          `(defstruct astruct ,@lst))
DEF-ASTRUCT
CL-USER> (macroexpand-1 '(def-astruct alist))
(DEFSTRUCT ASTRUCT . ALIST)
T

Hmm, what's wrong?

TIA,
  Michele

From: Arie van Wingerden
Subject: Re: A simple(?) macro
Date: 
Message-ID: <68b19$4337d538$3e3ba7c9$17167@news.versatel.nl>
Hi Michele,

the "problem" you encounter is caused by the fact that DEFMACRO does not 
evaluate it's arguments.

You could try something like this:

(defmacro def-astruct (lst)
   (let ((x (eval lst)))
     `(defstruct astruct ,@x)))

HTH,
    Arie


Michele Lamarca wrote:
> Hello everyone,
> I'm a Lisp novice, so I'm experimenting with simple macros.
> 
> CL-USER> (setf alist '(a b))
> (A B)
> CL-USER> `(defstruct astruct ,@alist)
> (DEFSTRUCT ASTRUCT A B)
> 
> Ok, that's the result I expect.
> 
> CL-USER> (defmacro def-astruct (lst)
>           `(defstruct astruct ,@lst))
> DEF-ASTRUCT
> CL-USER> (macroexpand-1 '(def-astruct alist))
> (DEFSTRUCT ASTRUCT . ALIST)
> T
> 
> Hmm, what's wrong?
> 
> TIA,
>   Michele
> 
From: Peter Seibel
Subject: Re: A simple(?) macro
Date: 
Message-ID: <m2irwnol67.fsf@gigamonkeys.com>
Arie van Wingerden <······@zonnet.nl> writes:

> Hi Michele,
>
> the "problem" you encounter is caused by the fact that DEFMACRO does
> not evaluate it's arguments.
>
> You could try something like this:
>
> (defmacro def-astruct (lst)
>    (let ((x (eval lst)))
>      `(defstruct astruct ,@x)))

However that's really not what you want to do because that doesn't
work when you try:

  (let ((some-list '(a b)))
    (def-astruct some-list))

because EVAL can't see the compile time lexical environment. It also
won't necessarily work if you try to COMPILE-FILE a file containing
uses of DEF-ASTRUCT because the value of ALIST won't necessarily be
available in the environment in which macro expanders run.

It's important to understand that the arguments to macros are the
*forms* that appear in the code, in this case the symbol ALIST. Macros
can expand into something that includes those forms in a position that
they will be evaluated when the code generated by the macro is
evaluated. But at the time you are expanding the macro the forms can't
be reliably evaluated because the other code that would give them
values hasn't necessarily run yet.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Michele Lamarca
Subject: Re: A simple(?) macro
Date: 
Message-ID: <1127773491.484085.265340@f14g2000cwb.googlegroups.com>
So the definition of def-astruct is complicated from the fact that
defstruct is a macro itself.

(defun def-astruct (lst)
  (eval
    `(defstruct astruct ,@lst)))

This seems to work.

Michele
From: Arie van Wingerden
Subject: Re: A simple(?) macro
Date: 
Message-ID: <a173a$43396218$3e3ba7c9$25973@news.versatel.nl>
Hi Michele,

of course Peter is right!

I must confess that writing Lisp macro's is a quite new experience for 
me as well, so lots to learn there for me!

Your solution seems to work properly and is elegant as well. In fact I 
didn't know that the backquote syntax could be used outside macro's; 
thanks for sharing that knowledge!

Kind regards,
	Arie

Michele Lamarca wrote:
> So the definition of def-astruct is complicated from the fact that
> defstruct is a macro itself.
> 
> (defun def-astruct (lst)
>   (eval
>     `(defstruct astruct ,@lst)))
> 
> This seems to work.
> 
> Michele
>