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
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/
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
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
>