Macros Lisp:在宏中展开属性名称

Macros Lisp:在宏中展开属性名称,macros,lisp,common-lisp,clisp,gnu-common-lisp,Macros,Lisp,Common Lisp,Clisp,Gnu Common Lisp,考虑以下属性列表: (defvar *some-variable* (list :foo "fooval" :bar "barval")) 这个简单的电话: (getf *some-variable* :foo) 按预期生成“fooval”。我定义了一个宏,除了可以传递要检索的任何属性的名称外,该宏也应该执行相同的操作: (defmacro my-macro (property-name) `(getf *some-variable* :,property-name)) 不幸的是,

考虑以下属性列表:

(defvar *some-variable* (list :foo "fooval" :bar "barval"))
这个简单的电话:

(getf *some-variable* :foo)
按预期生成
“fooval”
。我定义了一个宏,除了可以传递要检索的任何属性的名称外,该宏也应该执行相同的操作:

(defmacro my-macro (property-name)
    `(getf *some-variable* :,property-name))
不幸的是,这样称呼它:

(my-macro 'foo)

结果显示
FOO
。为什么?

你为什么不自己去看看呢:

(宏扩展-1'(我的宏“foo”)
; ==> (getf*某些变量*:||'foo);
T
表示如果给它第四个参数,则它是找不到键时的值。由于
:| |
(关键字包中的空符号)不存在,它将返回提供的默认
foo

因此,这里有一个函数可以满足您的要求:

(定义获取字段(名称)
(getf*某些变量*
(实习生(符号名称“关键字”))
(defparameter*test*'foo)
(获取字段*测试*)
; ==> “fooval”
将其设置为宏的唯一原因是将其设置为语法,语法和函数之间的主要区别在于不计算参数

(defmfield(名称)
`(获取字段',名称))
(接费菲)
; ==> “fooval”
(获取mfield*测试*)
; ==> 无

您可以使用简单的文本,但是您失去了将
*test*
视为变量而不是键的特性
:*test*

为什么不自己检查一下呢:

(宏扩展-1'(我的宏“foo”)
; ==> (getf*某些变量*:||'foo);
T
表示如果给它第四个参数,则它是找不到键时的值。由于
:| |
(关键字包中的空符号)不存在,它将返回提供的默认
foo

因此,这里有一个函数可以满足您的要求:

(定义获取字段(名称)
(getf*某些变量*
(实习生(符号名称“关键字”))
(defparameter*test*'foo)
(获取字段*测试*)
; ==> “fooval”
将其设置为宏的唯一原因是将其设置为语法,语法和函数之间的主要区别在于不计算参数

(defmfield(名称)
`(获取字段',名称))
(接费菲)
; ==> “fooval”
(获取mfield*测试*)
; ==> 无

你可以使用简单的文本,但是你失去了
*test*
被视为变量而不是键的功能
:*test*

使用MACROEXPAND来调试它。@RainerJoswig:我已经试过了,但我仍然不知道。它返回了什么?似乎还没有人指出
:,x
本质上是,语法错误。你不能用
来拼接符号语法中的东西:这就像你说的
make-,foo
来尝试创建一些符号一样虚假。如果你想在特定的软件包中构造符号,你必须做更多的工作。@RainerJoswig谢谢!我应该在发表我的评论之前尝试一下:我想我假设一致性解释是CLISP的,但我实际上不确定,也许只是不清楚它是否合法。很明显,它没有做到OP想要的。这种错误往往来自于使用“字符串中的语言”宏系统,如(抖动)Jinja2。使用MACROEXPAND来调试它。@RainerJoswig:我已经尝试过了,但仍然不清楚。它返回了什么?似乎还没有人指出,
:,x
本质上是一个语法错误。你不能用
来拼接符号语法中的东西:这就像你说的
make-,foo
来尝试创建一些符号一样虚假。如果你想在特定的软件包中构造符号,你必须做更多的工作。@RainerJoswig谢谢!我应该在发表我的评论之前尝试一下:我想我假设一致性解释是CLISP的,但我实际上不确定,也许只是不清楚它是否合法。很明显,它没有做到OP想要的。这种错误往往来自于使用“字符串中的语言”宏系统,如(抖动)Jinja2。