当使用另一个宏多次应用宏时,裸符号不会插入到当前上下文中:
(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可能会更好。
答案 0 :(得分:5)
(defmacro empties [& args]
(doseq [arg args]
`(ty ~arg)))
(empties Base Person Animal)
;equivalent to:
;(ty Base)
;(ty Person)
;(ty Animal)
这是错误的。您的empties
来电意味着empties
的宏扩展功能会将符号Base
,Person
和Animal
作为参数。然后它会为每个调用ty
宏调用,但不返回任何内容,因为doseq
总是返回nil。因此,empties
调用的扩展代码为零。您需要从宏函数返回单个表单。您应该将多个表单包装到do
中,并实际将所有子表单返回到:
(defmacro empties [& args]
`(do ~@(map (fn [arg]
`(ty ~arg))
args)))
答案 1 :(得分:2)
FWIW,我更喜欢将@ Svante的解决方案写成
(defmacro empties [& args]
(cons `do
(for [arg args]
`(ty ~arg))))
这也非常接近doseq
方法的结构。