将向量作为绑定传递给for宏的问题

Tef*_*Mac 9 binding list-comprehension clojure

我有任意数量的列表,我想使用for宏处理.我想创建一个函数,它将向量作为绑定传递,因为列表的数量不同.

如果我硬编码绑定,它按预期工作:

=> (def list1 '("pink" "green"))
=> (def list2 '("dog" "cat"))
=> (for [A list1 B list2] (str A "-" B))
("pink-dog" "pink-cat" "green-dog" "green-cat")
Run Code Online (Sandbox Code Playgroud)

当我尝试单独创建一个向量并使用它作为绑定我遇到了问题.在这里,我手动创建绑定向量:

=> (def testvector (vec (list 'A list1 'B list2)))
Run Code Online (Sandbox Code Playgroud)

这似乎很好:

=> testvector
[A ("pink" "green") B ("dog" "cat")]
=> (class testvector)
clojure.lang.PersistentVector
Run Code Online (Sandbox Code Playgroud)

然而,

=> (for testvector (str A "-" B))
#<CompilerException java.lang.IllegalArgumentException: for requires a vector for its binding (NO_SOURCE_FILE:36)>
Run Code Online (Sandbox Code Playgroud)

我不明白为什么testvector在被用作for的绑定时不被认为是一个向量.抓住吸管,我把testvector放在方括号中,这样可以保持宏的快乐(它看到一个向量)但现在我有一个带有一个元素的向量(即向量中的向量),这不起作用,因为绑定需要成对的名称和集合.

=> (for [testvector] (str A "-" B))
#<CompilerException java.lang.IllegalArgumentException: for requires an even number of forms in binding vector (NO_SOURCE_FILE:37)>
Run Code Online (Sandbox Code Playgroud)

关于如何动态地将矢量作为绑定传递给for的任何建议都将受到赞赏.

G__*_*G__ 5

关键是for是一个宏.在宏扩展时,testvector是一个符号.它将评估在评估时间的载体,但它不是从的角度矢量宏.

user=> (defmacro tst [v] (vector? v))
#'user/tst
user=> (tst testvector)
false
user=> (vector? testvector)
true
user=> (defmacro tst2 [v] `(vector? ~v))
#'user/tst2
user=> (tst2 testvector)
true
Run Code Online (Sandbox Code Playgroud)

如果你检查源为宏(在core.clj),你会看到,对于使用不带引号的载体?呼叫,就像上面例子中的tst一样.