宏迭代未定义的符号

Dan*_*iro 3 macros metaprogramming clojure

当使用另一个宏多次应用宏时,裸符号不会插入到当前上下文中:

(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)
Run Code Online (Sandbox Code Playgroud)

最后一行给出:"无法解析符号:在此上下文中为空",即使使用直接宏ty,它也可以.有办法解决这个问题吗?如果没有eval可能会更好.

Sva*_*nte 5

(defmacro empties [& args]
  (doseq [arg args]
    `(ty ~arg)))

(empties Base Person Animal)
;equivalent to:
;(ty Base)
;(ty Person)
;(ty Animal)
Run Code Online (Sandbox Code Playgroud)

这是错的.您的empties通话意味着宏扩展功能,empties获得作为参数的符号Base,PersonAnimal.然后它会ty为每个宏调用求值,但不会返回任何内容,因为它doseq总是返回nil.因此,该empties调用的扩展代码为零.您需要从宏函数返回单个表单.您应该将多个表单包装成一个do,并实际返回所有子表单:

(defmacro empties [& args]
  `(do ~@(map (fn [arg]
               `(ty ~arg))
              args)))
Run Code Online (Sandbox Code Playgroud)