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

Macros 如何处理Clojurescript宏中所需的Clojurescript代码?,macros,clojure,clojurescript,Macros,Clojure,Clojurescript,假设我有一个X.clojurescript和一个X.clojure名称空间。clojurescript中的所有内容都是clojurescript代码,X.clojure中的所有内容都是clojure代码。不幸的是,我不能在Clojurescript中直接定义宏,我必须在Clojure中定义宏,然后使用 (ns X.clojurescript.abc (:require-macros [X.clojure.def :as clj])) 这很好。但是,如果宏(在X.clojure中定义)需要引

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

(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端某些内容的宏?

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

您可以在repl中按照以下示例操作:

(defmacro foo
  [a]
  `(bar/bar ~a))
即使bar不是已定义的命名空间,也会编译foo的定义

(foo :a)
(ns user)
(foo :a)
调用foo现在将失败,因为您尚未定义bar名称空间或函数栏

(ns bar)
(defn bar
  [x]
  [x x])
在bar命名空间中定义bar

(foo :a)
(ns user)
(foo :a)
=>[:a:a]


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

使您的宏以clojurescript中所有必需的内容作为参数。如果你能添加一些代码,回答你的特殊问题就会容易得多。我想我不明白你的问题。宏必须生成代码,然后在clojurescript中对其求值。因此,如果您必须引用任何clojurescript def,那么在宏的扩展中生成符号就足够了吗?
请在宏扩展时引用clojurescript侧的某些内容
,否则这些内容将在输出代码中发出。编译是一回事,但是在ClojureScript方面需要一个库呢?在上面的示例中,您似乎需要在调用foo宏的ClojureScript模块中使用bar名称空间,这意味着调用模块必须了解宏的实现细节。我提到的问题的一个例子就是Hiccups库。您可以在这里看到他们的解决方案,这有点骇人:我认为这是clojurescript实现存在的一个基本问题。我提出的建议是我认为最好的解决方法,但我确实明白这并不理想。但从根本上讲,这与在纯clojure代码中使用宏没有什么不同——宏在调用时查找它为之生成符号的函数。