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