Clojure宏问题

Clojure宏问题,clojure,Clojure,我试图创建一个函数来创建一个以另一个结构为基础的新结构,作为开始,我试图创建一个宏来创建一个与旧结构具有相同字段的新结构。下面是我认为应该执行此操作的宏,但它给出了以下错误: java.lang.Exception: Can't use qualified name as parameter: user/p1__132 宏: (defmacro prototype [structure obj] `(apply struct ~structure (map #(~obj %) (keys

我试图创建一个函数来创建一个以另一个结构为基础的新结构,作为开始,我试图创建一个宏来创建一个与旧结构具有相同字段的新结构。下面是我认为应该执行此操作的宏,但它给出了以下错误:

java.lang.Exception: Can't use qualified name as parameter: user/p1__132 
宏:

(defmacro prototype [structure obj]
  `(apply struct ~structure (map #(~obj %) (keys ~obj))))
使用示例:

(defstruct bintree :data :left :right)
(def a (struct bintree 3))
(prototype bintree a)
在这种情况下,所需的输出是

{:data 3 :left nil :right nil}

这里有一个固定版本:

(defmacro prototype [structure obj]
  `(apply struct ~structure (map ~obj (keys ~obj))))
为什么这需要是一个宏?函数也起作用:

(defn prototype [structure obj]
  (apply struct structure (map obj (keys obj))))
为什么要复制结构?结构是不可变的,所以复制它们是没有用的。此函数的作用与上述函数相同:

(defn prototype [structure obj] obj)

如果您想创建一个包含其他键和值的新结构,请使用
assoc

作为问题注释发布的链接seth包含答案(罪魁祸首是匿名函数的参数处理方式);使用gensym参数,以下操作应有效:

(defmacro prototype [structure obj]
  `(apply struct ~structure (map (fn [x#] (~obj x#)) (keys ~obj))))
您不应该在宏中使用
#()

user> (macroexpand-1 `(foo #(bar %) baz)) (user/foo (fn* [user/p1__2047] (user/bar user/p1__2047)) user/baz) 用户>(宏扩展-1`(foo#(bar%)baz)) (用户/foo(fn*[user/p1_uu2047](用户/bar用户/p1_u2047))用户/baz)
并不是说
fn*
表单的参数列表中有名称空间限定符号。这就是你所犯的错误。您应该避免在宏中使用这种特殊的读取器语法,而是使用长格式。

我是clojure的新手,但我发现了以下链接:您能将所需的输出添加到使用示例中吗