这是我的宏,应该做的是用来自body
的绑定将let
包裹在vars-alist
中
(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)
返回t
。
错误可能有一些简单的解决方法,但我只是找不到它。
答案 0 :(得分:3)
请记住,宏的参数是未经评估的 ,这意味着当您将my-vars-alist
作为参数传递时,将逐字传递为 symbol { {1}}。
因此,在宏扩展期间,my-vars-alist
的计算结果为符号vars-alist
,而不是列表my-vars-alist
。
因此错误不是在抱怨变量 ((var1 . "var1") (var2 . "var2"))
并不包含作为其值,而是符号 my-vars-alist
不是本身序列(正确-是符号)。
my-vars-alist
对其进行检查,返回(sequencep my-vars-alist)
。
这也是正确的,因为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
的表格(或使用 M-x macroexpand-1
)。
答案 1 :(得分:2)
我看起来您想做的就是将清单的键与其值绑定,因此您可以将这些键用作let主体中的变量。最近的Emacs中有一个内置的宏:
(let-alist '((a . 1) (b . 2))
(message "a: %d, b: %d" .a .b))