如何处理Clojurescript宏中所需的Clojurescript代码?

时间:2013-02-08 21:47:55

标签: macros clojure clojurescript

我们假设我有一个X.clojurescript和一个X.clojure命名空间。 X.clojurescript中的所有内容都是Clojurescript代码,X.clojure中的所有内容都是Clojure代码。不幸的是,我不能直接在Clojurescript中定义宏,我必须在Clojure中定义它们然后使用

将它们带入Clojurescript命名空间。
(ns X.clojurescript.abc
  (:require-macros [X.clojure.def :as clj]))

这很好。但是,如果宏(在X.clojure中定义)需要引用Clojurescript命名空间(X.clojurescript)中定义的内容,该怎么办?问题是Clojure编译器在解析其他命名空间时不会查看我的Clojurescript命名空间(单独的目录)。

我通过简单地在我的Clojure代码中创建一个命名空间来解决这个问题,该命名空间具有与Clojurescript中相同的命名空间和所需的定义,但这看起来有点愚蠢。所以,例如,如果我在我的宏中需要X.clojurescript.abc.y,我将在Clojure端创建一个额外的命名空间,在我的Clojure版本的X.clojurescript.abc中定义一个虚拟y;有点傻。

如何处理需要在Clojurescript方面引用某些内容的宏?

1 个答案:

答案 0 :(得分:6)

宏在定义时唯一需要特定命名空间的时间是宏是否使用来自所述命名空间的代码来生成它将返回的符号列表。

您可以在repl中跟随这些示例:

(defmacro foo
  [a]
  `(bar/bar ~a))

即使bar不是已定义的命名空间,foo的定义也会编译

(foo :a)

调用foo现在会失败,因为你还没有定义bar命名空间或函数栏

(ns bar)
(defn bar
  [x]
  [x x])

在bar命名空间中定义bar

(ns user)
(foo :a)

=> [:a:a]

请注意,在foo定义时,bar不需要存在。事实上,在foo定义时,名称空间甚至不需要存在。