【问题标题】:Predefining functions that are automatically generated with Common Lisp macros使用 Common Lisp 宏自动生成的预定义函数
【发布时间】:2015-05-20 03:11:07
【问题描述】:

宏可以在全局范围内创建函数。例如:

(defmacro test-macro (&body functions)
 `(progn ,@(loop for function in functions
               collect `(defun ,function ()
                           *some-interesting-thing*))))

另一个例子(尽管有方法)是为 CLOS 类自动生成的访问器。

函数不是在宏扩展时定义的,而是在编译/解释生成的代码时定义的。这可能会导致一些困难。如果这些功能是预期的,则会引发警告。在正确定义这些函数之前定义它们的惯用方法是什么?一种可能的解决方案可能如下:

(defmacro test-macro (&body functions)
  (macrolet ((empty-function (name)
                `(defun ,name ())))
    (dolist (function functions)
       (empty-function function)))
  `(progn ,@(loop for function in functions
                collect `(defun ,function ()
                            *some-interesting-thing*))))

注意中间函数是在宏扩展时定义的。

【问题讨论】:

  • 您描述的问题(据我了解)不应该存在(根据规范)并且不存在(在我知道的任何实现中)。您能否提供明确的代码示例?

标签: function macros common-lisp


【解决方案1】:

如果你需要在编译时在顶层定义一个函数,那么使用:

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

请注意,您可以定义一个生成此类代码的宏。这样的表单可以是PROGN 的一部分。

【讨论】:

  • 在大多数情况下,如果你在顶层使用eval-when,你想要所有的(:compile-toplevel :load-toplevel :execute)
  • @Svante:我不会这么说。常见的 Lisp 实现使用 :compile-toplevel 通常用于仅编译时的副作用。例如DEFUN 在编译时注释该函数,但没有定义它。通常这是一个有用的模式。 eval-when 也只在所谓的顶层才有意义。除此之外没有任何实际用途。请注意,“顶层”在编译上下文中具有特殊含义,PROGN 中的表单仍处于“顶层”。
猜你喜欢
  • 2018-09-06
  • 2020-09-18
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2011-03-08
  • 2022-11-16
相关资源
最近更新 更多