如何使用带有内部函数的Clojure - >宏

ber*_*ert 3 clojure

我是Clojure初学者,我想了解->

此代码有效:

(-> '(1 2 3) reverse)
Run Code Online (Sandbox Code Playgroud)

但这甚至没有编译,我不知道如何处理错误消息:

user=> (-> '(1 2 3) (fn [x] (reverse x)))
Run Code Online (Sandbox Code Playgroud)

CompilerException java.lang.IllegalArgumentException:参数声明引用应该是一个向量,编译:(NO_SOURCE_PATH:1:1)

我怎样才能解决这个问题?

ove*_*ink 6

macroexpand当意想不到的事情开始发生时,我会和朋友们一起使用.如果你在这里使用它们,那么发生了什么变得非常明显.

user=> (macroexpand-1 '(-> '(1 2 3) (fn [x] (reverse x))))
(fn (quote (1 2 3)) [x] (reverse x))
Run Code Online (Sandbox Code Playgroud)

我认为看到这一点很明显,(quote (1 2 3)不应该是第一个arg fn.

我们还可以看到丑陋的双重方法解决了它:

user=> (macroexpand-1 '(-> '(1 2 3) ((fn [x] (reverse x)))))
((fn [x] (reverse x)) (quote (1 2 3)))
Run Code Online (Sandbox Code Playgroud)

让我沮丧的旁注:你必须在macroexpand-1这里得到一个结果.如果您在第一次扩展后使用macroexpand或者clojure.walk/macroexpand-all它会爆炸(除了您的例外),因为fn它本身就是一个宏,并且在第一次扩展后被调用语法错误.