From: Juliusz Chroboczek
Subject: Macro expansion
Date: 
Message-ID: <dh3zpunkqyd.fsf@calvay.dcs.ed.ac.uk>
A few simple questions about writing macros in Common Lisp.

I have a function which is used at macro-expansion time.  What
is the right eval-when form to wrap around its definition:

  (eval-when (compile load)
    (defun foo ...

or

  (eval-when (compile load eval)
    (defun foo ...

I would naturally use the former, but the CMUCL sources use the latter.

Another macro varies its expansion on whether a constant is set or no
(simple conditional compilation, a la C).  Namely,

  (defconstant *debug-strategies-flag* nil)

  (defmacro when-debug (&body body)
    (if (not *debug-strategies-flag*)
        'nil
      `(progn ,@body)))

Should the `defconstant' form be wrapped into an `eval-when', or
should the value of the constant be available at compile time anyway?
CMUCL does not need the `eval-when', but Haible's CLISP does (I'm
using an old version, though).

And finally, in CMUCL, this `when-debug' macro gives me a warning
about unreachable code every time I compile it.  Is there any way to
get rid of it?  Or should I handle the conditional compilation in an
altogether different way?  (Please note that the code is
computationally intensive, and I definitely want the debugging calls
to go away when I'm not debugging; I would not want to have to count
on the optimizer.)

Thank you very much,

                                        J.

From: Barry Margolin
Subject: Re: Macro expansion
Date: 
Message-ID: <5jrk1t$ur@tools.bbnplanet.com>
In article <···············@calvay.dcs.ed.ac.uk>,
Juliusz Chroboczek  <···@dcs.ed.ac.uk> wrote:
]A few simple questions about writing macros in Common Lisp.
]
]I have a function which is used at macro-expansion time.  What
]is the right eval-when form to wrap around its definition:
]
]  (eval-when (compile load)
]    (defun foo ...
]
]or
]
]  (eval-when (compile load eval)
]    (defun foo ...
]
]I would naturally use the former, but the CMUCL sources use the latter.

If both COMPILE and LOAD are specified, it's as if EVAL were also specified
when you're in the interpreter; this way, executing a form in the
interpreter is assured of being equivalent to compiling and loading a file
containing the form.  See the part of section 5.3.3 of CLtL2 that begins
with "If the situation LOAD is specified".

]Another macro varies its expansion on whether a constant is set or no
](simple conditional compilation, a la C).  Namely,
]
]  (defconstant *debug-strategies-flag* nil)
]
]  (defmacro when-debug (&body body)
]    (if (not *debug-strategies-flag*)
]        'nil
]      `(progn ,@body)))
]
]Should the `defconstant' form be wrapped into an `eval-when', or
]should the value of the constant be available at compile time anyway?
]CMUCL does not need the `eval-when', but Haible's CLISP does (I'm
]using an old version, though).

Any value that needs to be available at compile time needs to be in an
EVAL-WHEN with COMPILE specified.  Without this, the compiler might set
things up so that it replaces the constant in code it's generating into the
compiled file, but it's not expected to modify the compile-time
environment.

]And finally, in CMUCL, this `when-debug' macro gives me a warning
]about unreachable code every time I compile it.  Is there any way to
]get rid of it?  Or should I handle the conditional compilation in an
]altogether different way?  (Please note that the code is
]computationally intensive, and I definitely want the debugging calls
]to go away when I'm not debugging; I would not want to have to count
]on the optimizer.)

Since *debug-strategies-flag* is a constant, the compiler is propagating
this constant into the generated code for the macro.  You should use
DEFPARAMETER or DEFVAR.

The code generated for *users* of the macro will still leave out the
debugging code when *debug-strategies-flag* is nil -- your macro does that,
not the optimizer.
-- 
Barry Margolin
BBN Corporation, Cambridge, MA
······@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)
From: Pierpaolo Bernardi
Subject: Re: Macro expansion
Date: 
Message-ID: <5k1tie$10eu$2@pania.unipi.it>
Juliusz Chroboczek (···@dcs.ed.ac.uk) wrote:
: A few simple questions about writing macros in Common Lisp.

: I have a function which is used at macro-expansion time.  What
: is the right eval-when form to wrap around its definition:

:   (eval-when (compile load)
:     (defun foo ...

: or

:   (eval-when (compile load eval)
:     (defun foo ...

(eval-when (eval compile)
  (defun foo... ))

You don't need the function loaded, right?


: Another macro varies its expansion on whether a constant is set or no
: (simple conditional compilation, a la C).  Namely,

:   (defconstant *debug-strategies-flag* nil)

:   (defmacro when-debug (&body body)
:     (if (not *debug-strategies-flag*)
:         'nil
:       `(progn ,@body)))

: Should the `defconstant' form be wrapped into an `eval-when', or
: should the value of the constant be available at compile time anyway?
: CMUCL does not need the `eval-when', but Haible's CLISP does (I'm
: using an old version, though).

I think Clisp is correct.


: And finally, in CMUCL, this `when-debug' macro gives me a warning
: about unreachable code every time I compile it.  Is there any way to
: get rid of it?  Or should I handle the conditional compilation in an
: altogether different way?  (Please note that the code is
: computationally intensive, and I definitely want the debugging calls
: to go away when I'm not debugging; I would not want to have to count
: on the optimizer.)

You may use read-time conditionalization.
E.g.

;; use only one of these
(pushnew :debugging *features*)
(setf *features* (remove :debugging *features*))

(defmacro when-debug (&body body)
  #+debugging '(progn ,@body)    ;; The backquote is not working on this kbd.
  #-debugging nil)

Hope this helps.
Pierpaolo Bernardi.
From: Pekka P. Pirinen
Subject: Re: Macro expansion
Date: 
Message-ID: <ixrafvezge.fsf@gaspode.cam.harlequin.co.uk>
········@cli.di.unipi.it (Pierpaolo Bernardi) writes:

> Juliusz Chroboczek (···@dcs.ed.ac.uk) wrote:
> : Should the `defconstant' form be wrapped into an `eval-when', or
> : should the value of the constant be available at compile time anyway?
> : CMUCL does not need the `eval-when', but Haible's CLISP does (I'm
> : using an old version, though).
> 
> I think Clisp is correct.

They're both correct: according to the standard, the value of the
constant might or might not be available to a macro expander at
compile time.  A portable program should do 

(eval-when (compile eval)
  (defconstant *debug-strategies-flag* nil))

to make sure.  (Again, you probably don't need this constant at run
time, so no LOAD, but EVAL is smart in case you ever load this file
interpreted.)
-- 
Pekka P. Pirinen   Harlequin Limited, Cambridge, UK
"You're always going to build a prototype -- the only question
is whether you're going to deliver it to the customer."
  - Bob Martin, Bellcore