注意:这不是关于并发性的。这是关于线程宏。
我知道->
将对象放在第二个位置,->>
将参数放在最后一个位置。
现在,我很好奇,就像函数的#( ... % )
的简写符号一样,是否有一个简短的线程表示法让我将参数放在任意位置?
目标是不是让线程有一个固定的位置来运行...我可以编写任意形式,并在特殊位置插入%%,%%是插入线程的位置。
谢谢!
答案 0 :(得分:34)
现在在Clojure中有一个广义的线程宏,从1.5开始称为as->。
此推文举例说明了它的工作原理:https://twitter.com/borkdude/status/302881431649128448
(as-> "/tmp" x
(java.io.File. x)
(file-seq x)
(filter (memfn isDirectory) x)
(count x))
首先'x'绑定到“/ tmp”并从中生成一个文件。 'x'再次反弹到生成的文件,并通过'file-seq'函数等等。
答案 1 :(得分:26)
来自Swiss Arrows图书馆的'钻石魔杖'可以满足您的需求:
(-<> 0
(* <> 5)
(vector 1 2 <> 3 4))
; => [1 2 0 3 4]
那就是说,这不是你经常需要的(或者曾经在我的Clojure体验中)
答案 2 :(得分:15)
如果有其他人遇到这个问题,那么提供的宏存在一个原因,但是任意放置的宏都没有:后者会导致API设计不佳。
->
宏将参数放在第一个位置。这对应于处理某些主题论证的函数,例如conj
,assoc
。
->>
宏将参数放在最后一个位置。这对应于处理序列的函数,例如map
,reduce
。
很好地设计你的API,你不太可能需要这样的宏。
答案 3 :(得分:2)
有一个图书馆提供了这个功能,但我忘了在哪里。它可能是在弃用的clojure-contrib中。它是-$>
宏。
但你可以从clojure的核心-> macro派生出一个来制作你正在寻找的那个:
(defmacro -$>
([x] x)
([x form] (if (seq? form)
(with-meta (map #(if (= %1 '$) x %1) form) (meta form))
(list form x)))
([x form & more] `(-$> (-$> ~x ~form) ~@more)))
并使用$表示插入点:
user=> (-$> 2 str (identity $) (println $))
2
nil
从技术上讲,您可以在一种形式中使用多个$
。但是这种实现方式多次扩展相同的形式(换句简单)。