Emacs Lisp 宏不展开 Alist
Emacs Lisp Macro Does Not Expand Alist
这是我的宏,它应该做的是用 vars-alist
的绑定将 body
包装在 let
中
(defmacro with-vars-alist (vars-alist &rest body)
`(let (,@(mapcar (lambda (cell) (list (car cell) (cdr cell))) vars-alist))
,@body))
当我查看它使用以下代码扩展的内容时
(defvar my-vars-alist '((var1 . "var1")
(var2 . "var2")))
(macroexpand-1 (with-vars-alist my-vars-alist `(concat ,var1 ,var2)))
我得到一个错误 cons: Wrong type argument: sequencep, my-vars-alist
但是检查它 (sequencep my-vars-alist)
return t
。
这个错误可能有一些简单的解决方法,但我就是找不到。
请记住,宏的参数是 未计算的,这意味着当您将 my-vars-alist
作为参数传递时,它会作为 [=45= 逐字传递]符号 my-vars-alist
.
因此在宏扩展期间,vars-alist
计算为符号 my-vars-alist
而不是列表 ((var1 . "var1") (var2 . "var2"))
.
所以错误不是抱怨 变量 my-vars-alist
没有 包含 一个序列作为它的值,而是 符号 my-vars-alist
不是 本身 序列(这是正确的 - 它是一个符号)。
checking it (sequencep my-vars-alist)
return t
.
这也是正确的,因为 my-vars-alist
被评估为其值 ((var1 . "var1") (var2 . "var2"))
的变量
所以你需要eval
那个论点。例如:
,@(mapcar (lambda (cell) (list (car cell) (cdr cell)))
(eval vars-alist))
由于 vars-alist
已经 被计算为符号 my-vars-alist
,此更改意味着我们正在将符号 my-vars-alist
传递给 eval
,它将其作为一个变量求值以获得 mapcar
.
所需的列表
您可能还想引用传递给 macroexpand-1
的表单(或使用 M-x pp-macroexpand-last-sexp
)。
我看起来像你想做的是让一个列表的键绑定到它们的值,这样你就可以在 let 主体中使用这些键作为变量。在最近的 Emacs 中有一个内置的宏:
(let-alist '((a . 1) (b . 2))
(message "a: %d, b: %d" .a .b))
这是我的宏,它应该做的是用 vars-alist
body
包装在 let
中
(defmacro with-vars-alist (vars-alist &rest body)
`(let (,@(mapcar (lambda (cell) (list (car cell) (cdr cell))) vars-alist))
,@body))
当我查看它使用以下代码扩展的内容时
(defvar my-vars-alist '((var1 . "var1")
(var2 . "var2")))
(macroexpand-1 (with-vars-alist my-vars-alist `(concat ,var1 ,var2)))
我得到一个错误 cons: Wrong type argument: sequencep, my-vars-alist
但是检查它 (sequencep my-vars-alist)
return t
。
这个错误可能有一些简单的解决方法,但我就是找不到。
请记住,宏的参数是 未计算的,这意味着当您将 my-vars-alist
作为参数传递时,它会作为 [=45= 逐字传递]符号 my-vars-alist
.
因此在宏扩展期间,vars-alist
计算为符号 my-vars-alist
而不是列表 ((var1 . "var1") (var2 . "var2"))
.
所以错误不是抱怨 变量 my-vars-alist
没有 包含 一个序列作为它的值,而是 符号 my-vars-alist
不是 本身 序列(这是正确的 - 它是一个符号)。
checking it
(sequencep my-vars-alist)
returnt
.
这也是正确的,因为 my-vars-alist
被评估为其值 ((var1 . "var1") (var2 . "var2"))
所以你需要eval
那个论点。例如:
,@(mapcar (lambda (cell) (list (car cell) (cdr cell)))
(eval vars-alist))
由于 vars-alist
已经 被计算为符号 my-vars-alist
,此更改意味着我们正在将符号 my-vars-alist
传递给 eval
,它将其作为一个变量求值以获得 mapcar
.
您可能还想引用传递给 macroexpand-1
的表单(或使用 M-x pp-macroexpand-last-sexp
)。
我看起来像你想做的是让一个列表的键绑定到它们的值,这样你就可以在 let 主体中使用这些键作为变量。在最近的 Emacs 中有一个内置的宏:
(let-alist '((a . 1) (b . 2))
(message "a: %d, b: %d" .a .b))