宏扩展可以包含(声明...)表达式吗?

nbt*_*rap 5 lisp macros common-lisp

Common Lisp Hyperspec声明"宏表单不能扩展为声明;声明表达式必须显示为它们引用的表单的实际子表达式."

我对"扩展到"的含义感到困惑.由于以下原因,以下宏将无法正常工作:

(defmacro optimize-fully ()
    `(declare (optimize (speed 3) (safety 0))))
Run Code Online (Sandbox Code Playgroud)

但是,如果宏扩展只包含一个(declare ...)表达式呢?

(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))
Run Code Online (Sandbox Code Playgroud)

这违反了规范吗?我使用的CL实现,SBCL,并没有抱怨,事实上,上面的宏似乎正如预期的那样工作.是什么赋予了?

Xac*_*ach 13

你的第一个例子正是它所禁止的.你不可能有类似这样的代码:

(defun optimized (a b)
  (optimize-fully)
  (+ a b))
Run Code Online (Sandbox Code Playgroud)

我有时会看到这样的代码:

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

(defun foo (a b)
  (declare #.*optimization-settings*)
  ...)
Run Code Online (Sandbox Code Playgroud)

  • 是的,这就是它的含义. (3认同)
  • 所以当规范禁止从"扩展到声明"的宏调用时,它只是在讨论_immediate_(我想不出更好的词)扩展? (2认同)
  • 并且“Let Over Lambda”一书的作者建议定义扩展以声明表单的阅读器宏,因为阅读器宏在扩展普通宏之前得到扩展。 (2认同)