lisp - 将文档字符串合并到 def* 宏中的正确方法?

标签 lisp common-lisp sbcl defmacro

我正在通过 Practical Common Lisp 工作。我得到了定义 deftest 的示例。类似于 defun 的宏增加了一些功能。这让我想到能够添加一个文档字符串会很好。我发现以下两项都有效,但其中一项更正确吗?是否有一种“正确”的方式来实现 defun 的类似可选文档字符串的行为? ?

(defmacro deftest (name parameters &body body)
  (let ((docstring ""))
    (when (stringp (car body)) (setf docstring (car body) body (cdr body)))
    `(defun ,name ,parameters
       ,docstring
       (let ((*test-name* (append *test-name* (list ',name))))
         ,@body))))

(defmacro deftest (name parameters &optional docstring &body body)
  (when (not (stringp docstring)) (setf docstring ""))
  `(defun ,name ,parameters
     ,docstring
     (let ((*test-name* (append *test-name* (list ',name))))
       ,@body)))

最佳答案

通常,您可能希望从函数体中解析出可能的文档字符串和任何声明,因此您可以将声明放在它们所属的位置。我使用这样的东西:

(defun parse-body (body)
    (multiple-value-bind (docstring decls/forms)
        (if (stringp (first body))
            (values (first body) (rest body))
          (values nil body))
      (loop for remainder on decls/forms
            while (and (not (null remainder))
                       (consp (first remainder))
                       (eql (car (first remainder)) 'declare))
            collect (first remainder) into decls
            finally (return (values docstring decls remainder)))))
然后你的deftest将会
(defmacro deftest (name parameters &body body)
  (multiple-value-bind (docstring decls forms) (parse-body body)
    `(defun ,name ,parameters
       ,@(if docstring (list docstring) '())
       ,@decls
       (let ((*test-name* (append *test-name* (list ',name))))
         ,@forms))))
我希望我可以说我有一个标准 parse-body功能,但我没有:我只是每次都写一个新的。

关于lisp - 将文档字符串合并到 def* 宏中的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66364347/

相关文章:

lisp - 如何使用 ltk 显示图像?

lisp - 为什么 null 谓词称为 null,而不是 nullp?

format - Common Lisp格式指令中出现神秘的换行符

merge - 在 common lisp 中合并符号

lisp - 如何在 Common Lisp 中递增或递减一个数字?

lisp - 如何使用 SBCL 的 SB-SPROF 分配分析?

Lisp IO 问题

emacs - 什么时候应该使用 Emacs #'function 语法?

LISP In Small Pieces - 运行代码的最佳 LISP 环境?

list - 替换 Common Lisp 列表中的项目?