【问题标题】:Can macro expansion contain (declare ...) expressions?宏扩展可以包含 (declare ...) 表达式吗?
【发布时间】:2013-09-05 20:26:25
【问题描述】:

Common Lisp Hyperspec 声明“宏形式不能扩展为声明;声明表达式必须作为它们所引用的形式的实际子表达式出现。”

我对“扩展到”的含义感到困惑。出于显而易见的原因,如下所示的宏将不起作用:

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

但是如果宏扩展仅仅包含一个(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))

这是否违反规范?我使用的 CL 实现,SBCL,并没有抱怨,事实上,上面的宏似乎完全按预期工作。什么给了?

【问题讨论】:

    标签: macros lisp common-lisp


    【解决方案1】:

    您的第一个示例正是它所禁止的。你不能把这样的代码和这样的东西结合起来:

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

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

    (defvar *optimization-settings* '(optimize (speed 3) (safety 0)))
    
    (defun foo (a b)
      (declare #.*optimization-settings*)
      ...)
    

    【讨论】:

    • 所以当规范禁止宏调用从“expand[ing] into declarations”时,它只是在谈论立即(我想不出更好的词)扩展?
    • 是的,就是这个意思。
    • 而《Let Over Lambda》一书的作者建议定义扩展阅读器宏以声明表单,因为阅读器宏在普通宏扩展之前得到扩展。
    猜你喜欢
    • 2012-09-12
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 2018-10-20
    • 2011-06-23
    • 2012-02-13
    相关资源
    最近更新 更多