This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

multiple evaluation in macros

5 posts · 2408 views

Hi,

I'm trying to implement a macro that creates both a struct and a function. The following code template:
(defmacro macro-example (...)
  `(defstruct ...)
  `(defun  ....))
doesn't work since only the last element is actually evaluated and, therefore, the function is defined but the structure is not created. As a solution I could define a function that calls two macros: one for the function and another one for the struct but I was wondering if there is a way to do both things with just one macro. In other words, is it possible to generate two different pieces of code from one single macro?

Regards,
Luis.

Re: multiple evaluation in macros

Try this:
(defmacro macro-example (...)
  `(progn
     (defstruct ...)
     (defun  ....)))
Any other construct using an implicit PROGN will work, too.

- edgar

Re: multiple evaluation in macros

edgar-rft wrote:Any other construct using an implicit PROGN will work, too.
Although do note that top level PROGN is specified to preserved top-levelness of forms, while other forms are not. This is usually not critical, but can affect compilation in ways which I never investigated in detail, but it is best avoided.

Re: multiple evaluation in macros

edgar-rft wrote:Try this:
(defmacro macro-example (...)
  `(progn
     (defstruct ...)
     (defun  ....)))
Any other construct using an implicit PROGN will work, too.

- edgar
Thank you. I should have come up with this straightforward solution.

Regards,
Luiw

Re: multiple evaluation in macros

Edgar: Any other construct using an implicit PROGN will work, too.

Ramarren: Although do note that top level PROGN is specified to preserved top-levelness of forms, while other forms are not. This is usually not critical, but can affect compilation in ways which I never investigated in detail, but it is best avoided.
It's correct that PROGN is only guarateed to evaluate forms at the top-level if called at the top-level, so it's not guaranteed 100% for sure that code like this will work:
(defmacro macro-example (...)
  ;; some heavily nested Lisp forms, where
  ;; PROGN is called deep inside the nesting
  `(foo ...
     (bar ...
       (baz ...
         (progn
           (defstruct ...)
           (defun  ....))))))
Like Ramarren I have not investigated in really deep detail so far if this may cause problems in compiled code, but AFAIK both DEFSTRUCT as well as DEFUN are defined to manipulate symbols in the global and not in the lexical environment.

Counter-example: If DEFUN is called e.g. inside a LET scope like in this standard closure example, then the variable X inside the DEFUN will be of course clearly affected by the surrounding LET binding:
CL-USER> (defmacro macro-example ()
           `(let ((x 1))
              (defun add-x (arg) (+ arg x))))
MACRO-EXAMPLE

CL-USER> (macro-example)
ADD-X

CL-USER> (add-x 1)
2
Similar effects can easily happen if you don't mind the lexical environment where DEFSTRUCT or DEFUN are called.

- edgar