在宏之间传递状态

时间:2011-07-02 13:55:01

标签: macros clojure

在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"

澄清

  • 这需要在编译时使用宏进行,即不能在运行时使用常规函数

1 个答案:

答案 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