在Clojure编译时创建一组彼此共享信息的宏的最佳方法是什么?
我正在寻找一些方法让宏知道以前的宏已经做了什么,并采取相应的行动,例如你将如何实现可以像下面这样使用的宏:
(macro-block-with-data ["A" "B" "C"]
(process-next-data-item) ; macro expands using "A"
(process-next-data-item) ; macro expands using "B"
(process-next-data-item)) ; macro expands using "C"
澄清
答案 0 :(得分:3)
它是否有词汇范围?如果是这样,你可以做类似下面的事情,它使用有状态的迭代器(虽然有些丑陋)。
(defmacro process-next-data-item []
`(println "step" (.next ~'__state)))
(defmacro macro-block-with-data [dat & body]
`(do
(let [~'__state (.iterator ~dat)]
~@body)))
举个例子:
(defn test []
(macro-block-with-data ["A" "B" "C"]
(println "start")
(process-next-data-item) ; macro expands using "A"
(println "middle")
(process-next-data-item) ; macro expands using "B"
(println "almost done")
(macro-block-with-data [ "NestedA" "NestedB" ]
(println "starting nested")
(process-next-data-item)
(process-next-data-item)
(println "done nested"))
(process-next-data-item)
(println "done")))
......导致......
user> (test)
start
step A
middle
step B
almost done
starting nested
step NestedA
step NestedB
done nested
step C
done
nil