宏迭代未定义的符号
当与另一个宏多次应用一个宏时,裸符号不会插入到当前上下文中:
(defmacro ty [type]
`(deftype ~type []))
(defmacro empties [& args]
(doseq [arg args]
`(ty ~arg))
)
(empties Base Person Animal)
;equivalent to:
;(ty Base)
;(ty Person)
;(ty Animal)
(derive ::Person ::Base)
(derive ::Animal ::Base)
(ty Me)
(prn ::Me)
(prn Me)
(empties Empty)
(prn ::Empty)
(prn Empty)
最后一行给出:“无法解析符号:此上下文中为空”,即使在使用直接宏 ty 时,它也有效。有办法解决这个问题吗?如果可以不用 eval 就更好了。
When applying a macro multiple times with a another macro, bare Symbols are not inserted into the current context:
(defmacro ty [type]
`(deftype ~type []))
(defmacro empties [& args]
(doseq [arg args]
`(ty ~arg))
)
(empties Base Person Animal)
;equivalent to:
;(ty Base)
;(ty Person)
;(ty Animal)
(derive ::Person ::Base)
(derive ::Animal ::Base)
(ty Me)
(prn ::Me)
(prn Me)
(empties Empty)
(prn ::Empty)
(prn Empty)
The last line gives: "Unable to resolve symbol: Empty in this context", even though when using the direct macro ty, it works. Any way to solve this? If possible without eval it would be much better.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是错误的。您的
empties
调用意味着empties
的宏扩展函数获取符号Base
、Person
和 <代码>动物。然后,它对每个宏调用求值,但不返回任何内容,因为 doseq 始终返回 nil。因此,empties
调用的扩展代码为零。您需要从宏函数返回单个表单。您应该将多个表单包装到一个do
中,并实际上将所有子表单返回给该表单:This is wrong. Your
empties
call means that the macro expansion function forempties
gets as arguments the symbolsBase
,Person
, andAnimal
. It then evaluates thety
macro call for each, but does not return anything, asdoseq
always returns nil. So, the expanded code from thatempties
call is nil. You need to return a single form from your macro function. You should wrap the multiple forms into ado
, and actually return all the subforms to that:FWIW,我更喜欢编写@Svante 的解决方案,因为
它也非常接近您的
doseq
方法的结构。FWIW, I prefer to write @Svante's solution as
which is also pretty close to the structure of your
doseq
approach.