我可以从Clojure中的宏中引用宏吗?

我可以从Clojure中的宏中引用宏吗?,clojure,macros,Clojure,Macros,克罗朱尔。草书的答复。视窗10。所有都是最新的。 这是我的“基本”宏: (defmacro PutProp! [Sym Val PName] `(reset-meta! (var ~Sym) (assoc (meta (var ~Sym)) ~PName ~Val))) 我不知道这样做是否正确,我想做的就是用新的Val值修改Sym的元数据键名PName。我在这方面是新手,我肯定我已经跳进了游泳池的最深处。我之所以使用宏,是因为我认为它可以避免复杂的变量绑定问题,而我在Clojure中不了解

克罗朱尔。草书的答复。视窗10。所有都是最新的。

这是我的“基本”宏:

(defmacro PutProp! [Sym Val PName]
  `(reset-meta! (var ~Sym) (assoc (meta (var ~Sym)) ~PName ~Val)))
我不知道这样做是否正确,我想做的就是用新的Val值修改Sym的元数据键名PName。我在这方面是新手,我肯定我已经跳进了游泳池的最深处。我之所以使用宏,是因为我认为它可以避免复杂的变量绑定问题,而我在Clojure中不了解这些问题

然后我编写了另一个宏,在一次调用中定义了大量元数据:

(defmacro DefMeta! [L]  ;; Given a symbol (first L), define metadata for it given in (next L).
  `(let [S (first ~@L)]     ;; The symbol we're modifying is the first element in list L.
     (map (fn [[K V]] (PutProp! S V K)) (next ~@L))))   ;; (next L) is the list of key/value pairs.
我也不确定这是我想写的。 在REPL工作时,我定义了一个符号:

(def Sym 0)
然后我对DefMeta进行宏扩展-1!:

(macroexpand-1 '(DefMeta! [Sym :VName :VValue]))
我得到以下信息:

(clojure.core/let
 [thic.core/S (clojure.core/first Sym :VName :VValue)]
 (clojure.core/map
  (clojure.core/fn [[thic.core/K thic.core/V]] (thic.core/PutProp! thic.core/S thic.core/V thic.core/K))
  (clojure.core/next Sym :VName :VValue)))
这不会宏扩展PutProp!宏。

我被难住了。我有四本关于Clojure编程的书,其中没有一本提到来自宏调用内部的宏调用。这合法吗?如果是这样,我如何完全展开内部宏,以便查看我所写的内容是否符合我的要求?[…长期存在的程序员问题…]

PS我尝试了
macroexpand all
,我被所有东西的宏扩展淹没了,甚至包括Clojure核心函数。
请给我少一点。求你了

这不会宏扩展PutProp!宏

是,
macroexpand-1
只执行一次宏扩展。宏扩展的整个过程是一个不动点计算,其中每棵树都被扩展,直到它达到一个无法再扩展的形式

您可能想使用

此外,宏中的输入列表是表达式列表,您希望在宏扩展时获取该列表的第一个和下一个

(first ~@L)
上述内容扩展为:

(clojure.core/first Sym :VName :VValue)
实际上,您只需要
Sym
,即:

~(first L)
使用另一个宏定义宏是完全合法的(常见的)

您可以看到IMHO逐步建立宏的最佳方法的示例


我不喜欢使用
macroexpand-*
函数。上面链接中的答案使用带有
println
和friends的简单帮助函数,这样您就可以在宏写入过程中一步一步地看到发生了什么。享受吧

您是否可以添加所需用例和结果的示例?除非我遗漏了什么,
PutProp
不需要是宏,可以作为一个简单的函数编写(更可取)。此外,还可以是一个小的样式点。Clojure通常使用“kabob case”,比如
def meta用于名称。CamelCase名称,如
DefMeta
通常保留用于与Java类或它们的Clojure表兄弟、记录交互。如果您只想再进行一次扩展,为什么不调用第一次的结果
macroexpand-1
?谢谢!宏扩展的想法宏扩展非常有用。谢谢。我想我已经让它做了我想做的。“是的,它是合法的。”这是最有用的信息。我将在稍后跟进该链接。