Macros 为什么不允许在宏中引用参数

Macros 为什么不允许在宏中引用参数,macros,lisp,elisp,quote,Macros,Lisp,Elisp,Quote,最近我问了这个问题,但我想也许我会得到一个更好的答案 我编写的宏通常采用符号或符号列表,有时这些符号表示变量或函数。在这种情况下,我很想写宏,这样它们的参数就可以被引用或被引用。下面是一个具体的例子: 在emacs lisp中,函数add hook将hook-FN添加到名为hook的列表中 (添加hook'hook#'hook-fn) 通常,您希望将多个项目添加到钩子中,或者希望将HOOK-FN添加到多个钩子中,但添加钩子一次只接受一个钩子或一个钩子FN。所以,我为这个做了一个宏,叫做addh

最近我问了这个问题,但我想也许我会得到一个更好的答案

我编写的宏通常采用符号或符号列表,有时这些符号表示变量或函数。在这种情况下,我很想写宏,这样它们的参数就可以被引用或被引用。下面是一个具体的例子:

在emacs lisp中,函数add hook将hook-FN添加到名为hook的列表中

(添加hook'hook#'hook-fn)
通常,您希望将多个项目添加到钩子中,或者希望将HOOK-FN添加到多个钩子中,但添加钩子一次只接受一个钩子或一个钩子FN。所以,我为这个做了一个宏,叫做addhook!它可以接受多个参数

(添加钩子!钩子名称(fn1 fn2 fn3))
;; 或
(添加钩子!(钩子名称1钩子名称2)钩子fn)
我倾向于允许宏的片段被引用或锐化引用。就像在函数调用中一样

(添加hook!hook name#fn)
要做到这一点,我将使用这样的函数从每个参数中去掉引号

(defun unquote (form)
  "Unquote a form if it is quoted, otherwise return form."
  (if (member (car-safe it) '(quote function))
      (cadr form)
    form))
我之所以这样做,是因为引号和锐引号(1)明确了我指的是函数还是符号,(2)触发了我的自动补全,这有助于我更快地键入函数或符号


然而,我的印象是,这不是lisp中的惯例。为什么?是否有充分的理由不允许在宏中引用参数?

您当然可以这样做,但它看起来有点奇怪,因为它混合了“函数在这里,正常求值”和“宏在这里,特殊求值”的视觉信号

你为什么不把
addhook-fns
作为一个(相当简单的)函数,就像
addhook
一样?然后,所有的引用自然到位,甚至是必需的

(defun add-hook-fns (hook fns)
  (dolist (fn fns)
    (add-hook hook fn)))
这将在调用时显示如下:

(add-hook-fns 'some-hook (list #'foo #'bar #'baz))
如果您不想在其中显式调用
list
,可以使用宏来消除这一点:

(defmacro add-hook-fns* (hook fns)
  `(add-hook-fns ,hook (list ,@fns)))
等等:

(add-hook-fns* 'some-hook (#'foo #'bar #'baz))
但是,我不建议这样做,请在开始时查看原因

相反,我仍然只使用一个函数,但使用rest参数:

(defun add-hook-fns (hook &rest fns)
  (dolist (fn fns)
    (add-hook hook fn)))
现在:


你当然可以这样做,但它看起来有点奇怪,因为它混合了视觉信号,上面写着“函数在这里,正常评估”和“宏在这里,特殊评估”

你为什么不把
addhook-fns
作为一个(相当简单的)函数,就像
addhook
一样?然后,所有的引用自然到位,甚至是必需的

(defun add-hook-fns (hook fns)
  (dolist (fn fns)
    (add-hook hook fn)))
这将在调用时显示如下:

(add-hook-fns 'some-hook (list #'foo #'bar #'baz))
如果您不想在其中显式调用
list
,可以使用宏来消除这一点:

(defmacro add-hook-fns* (hook fns)
  `(add-hook-fns ,hook (list ,@fns)))
等等:

(add-hook-fns* 'some-hook (#'foo #'bar #'baz))
但是,我不建议这样做,请在开始时查看原因

相反,我仍然只使用一个函数,但使用rest参数:

(defun add-hook-fns (hook &rest fns)
  (dolist (fn fns)
    (add-hook hook fn)))
现在:


我认为一个词的答案是“品味”。我认为一个词的答案是“品味”。