Can macro expansion contain (declare ...) expressions?
Asked Answered
B

1

5

The Common Lisp Hyperspec states "Macro forms cannot expand into declarations; declare expressions must appear as actual subexpressions of the form to which they refer."

I'm confused on the meaning of "expand into". A macro such as the following won't work for obvious reasons:

(defmacro optimize-fully ()
    `(declare (optimize (speed 3) (safety 0))))

But what if the macro expansion merely contains a (declare ...) expression?

(defmacro defun-optimized (name (&rest lambda-list) &rest body)
    `(defun ,name ,lambda-list
        (declare (optimize (speed 3) (safety 0)))
        ,@body))

(defun-optimized foobar (a b)
    (* a b))

Is this a violation of the spec? The CL implementation I use, SBCL, does not complain, and in fact, the macro above seems to work precisely as expected. What gives?

Braithwaite answered 5/9, 2013 at 20:26 Comment(0)
T
14

Your first example is exactly what it's prohibiting. You couldn't have code like that combined with something like this:

(defun optimized (a b)
  (optimize-fully)
  (+ a b))

I sometimes see code like this, though:

(defvar *optimization-settings* '(optimize (speed 3) (safety 0)))

(defun foo (a b)
  (declare #.*optimization-settings*)
  ...)
Trigonal answered 5/9, 2013 at 20:41 Comment(3)
So when the spec prohibits macro calls from "expand[ing] into declarations", it's only talking about immediate (I can't think of a better word) expansions?Braithwaite
Yes, that's what it means.Trigonal
And the author of the book "Let Over Lambda" suggests defining reader macros that expand to declare forms, since reader macros get expanded before normal macros are expanded.Grimes

© 2022 - 2024 — McMap. All rights reserved.