无法使用我的 Emacs-Lisp 宏定义函数
Cannot define functions with my Emacs-Lisp macro
我正在尝试弄清楚如何使用宏。我知道还有其他方法可以解决这个问题,宏可能是也可能不是最好的答案,但我想了解这里的技术问题与其他方式解决它。
(setq model-names (list "goat" "alpaca" "llama"))
(defun some-fn (model tag)
(message "Great news: %s %s" model tag))
(defmacro make-my-defun(model)
`(defun ,(intern (concat "my-defun-" (eval model))) (tag)
"Do a thing"
(interactive "sTag: ")
(some-fn ,(eval model) tag)))
(macroexpand-1 '(make-my-defun "goat"))
(macroexpand-1 '(make-my-defun (car model-names)))
(cl-loop for name in model-names
do
;; (insert (format "%s" name)))
(make-my-defun name))
这几乎行得通。我知道传递给宏的东西只是 sexprs,而不是评估代码。但是,当我尝试在循环中创建这些函数时,它根本不起作用。使用上面的代码...
(make-my-defun "goat")
(make-my-defun (car model-names))
这两个都有效。如果没有 eval,它显然不会工作,因为它会在第二个语句中获取原始 car expr。
所以这是怎么回事?就 make-my-defun
而言,为什么 name
在我的 cl-loop
中是一个空变量?我阅读了有关宏的文档和其他一些资源,但是,我在这里缺乏一些基本的见解。
cl-loop
是......复杂的,但基本上,循环内的 name
绑定是通过 cl-symbol-macrolet
完成的,它扩展为解析绑定的代码。 eval
无法在调用时知道这一点:因为 (1) 您不希望 macroexpand
陷入引用代码; (2) 您不希望 eval
以某种方式继承周围的词法环境。当你写(car model-names)
时,它是全局绑定的。
你已经用过eval
一次,我想你可以再用一次:
(cl-loop for name in model-names
do (eval `(make-my-defun ,name)))
但实际上,宏对代码进行操作,它们通常不求值。
我正在尝试弄清楚如何使用宏。我知道还有其他方法可以解决这个问题,宏可能是也可能不是最好的答案,但我想了解这里的技术问题与其他方式解决它。
(setq model-names (list "goat" "alpaca" "llama"))
(defun some-fn (model tag)
(message "Great news: %s %s" model tag))
(defmacro make-my-defun(model)
`(defun ,(intern (concat "my-defun-" (eval model))) (tag)
"Do a thing"
(interactive "sTag: ")
(some-fn ,(eval model) tag)))
(macroexpand-1 '(make-my-defun "goat"))
(macroexpand-1 '(make-my-defun (car model-names)))
(cl-loop for name in model-names
do
;; (insert (format "%s" name)))
(make-my-defun name))
这几乎行得通。我知道传递给宏的东西只是 sexprs,而不是评估代码。但是,当我尝试在循环中创建这些函数时,它根本不起作用。使用上面的代码...
(make-my-defun "goat")
(make-my-defun (car model-names))
这两个都有效。如果没有 eval,它显然不会工作,因为它会在第二个语句中获取原始 car expr。
所以这是怎么回事?就 make-my-defun
而言,为什么 name
在我的 cl-loop
中是一个空变量?我阅读了有关宏的文档和其他一些资源,但是,我在这里缺乏一些基本的见解。
cl-loop
是......复杂的,但基本上,循环内的 name
绑定是通过 cl-symbol-macrolet
完成的,它扩展为解析绑定的代码。 eval
无法在调用时知道这一点:因为 (1) 您不希望 macroexpand
陷入引用代码; (2) 您不希望 eval
以某种方式继承周围的词法环境。当你写(car model-names)
时,它是全局绑定的。
你已经用过eval
一次,我想你可以再用一次:
(cl-loop for name in model-names
do (eval `(make-my-defun ,name)))
但实际上,宏对代码进行操作,它们通常不求值。