我是Clojure初学者,我想了解->
宏
此代码有效:
(-> '(1 2 3) reverse)
但是这甚至没有编译,我不知道如何处理错误信息:
user=> (-> '(1 2 3) (fn [x] (reverse x)))
CompilerException java.lang.IllegalArgumentException:参数声明引用应该是一个向量,编译:(NO_SOURCE_PATH:1:1)
我该如何解决这个问题?
答案 0 :(得分:6)
当意想不到的事情开始发生时,我会使用macroexpand
和朋友。如果你在这里使用它们,那么发生的事情就变得非常明显了。
user=> (macroexpand-1 '(-> '(1 2 3) (fn [x] (reverse x))))
(fn (quote (1 2 3)) [x] (reverse x))
我认为看到这一点很明显(quote (1 2 3)
不应该是fn
的第一个arg。
我们还可以看到丑陋的双重方法解决了这个问题:
user=> (macroexpand-1 '(-> '(1 2 3) ((fn [x] (reverse x)))))
((fn [x] (reverse x)) (quote (1 2 3)))
附带说明让我失望:你必须使用macroexpand-1
来获得结果。如果你使用macroexpand
或clojure.walk/macroexpand-all
它会在第一次扩展后爆炸(除了你的例外),因为fn
本身就是一个宏,并且在第一次调用之后被调用了错误的语法扩展