为什么clojure.string中split和join的参数位置混淆了?

为什么clojure.string中split和join的参数位置混淆了?,string,clojure,String,Clojure,我想这样做: (->字符串 (str/split“\s”) (修改-1) (修改-2) … (修改-n) (str/join“\n”)) 但是不是,拆分需要[s regex]和联接需要[separator coll] 这种疯狂有什么明显的原因吗(阅读:这背后的设计决定是什么)?您可以使用partial函数来修复str/join的分隔符参数 (-> string (str/split #"\s") (modification-1) (modification-2) ;;

我想这样做:

(->字符串
(str/split“\s”)
(修改-1)
(修改-2)
…
(修改-n)
(str/join“\n”))
但是不是,拆分需要
[s regex]
和联接需要
[separator coll]


这种疯狂有什么明显的原因吗(阅读:这背后的设计决定是什么)?

您可以使用partial函数来修复str/join的分隔符参数

(-> string
  (str/split #"\s")
  (modification-1)
  (modification-2)
  ;;
  (modification-n)
  ((partial str/join "\n")))

我也经常遇到这种(轻微的)穿线头痛

(-> string
    (str/split "\s")
    (modification-1)
    (modification-2)
    …
    (modification-n
    (#(str/join "\n" %)))

我猜想,为什么有些函数打算先与线程
->
一起使用,有些函数打算最后与线程
->
一起使用,而有些函数则不是设计目标,尽管这只是一个猜测。

从Clojure 1.5开始,您还可以使用一个新的threa丁宏

clojure.core/as->

([expr名称和表格])

将name绑定到expr,计算词法上下文中的第一个表单 然后将名称绑定到该结果,并对每个结果重复 连续窗体,返回最后一个窗体的结果

这是一个全新的结构,所以还不确定如何习惯地使用,但我想这样做可以:

(as-> "test test test" s
    (str/split s #" ")
    (modification-1 s)
    (modification-2 s)
    ...
    (modification-n s)
    (str/join "\n" s))
编辑

至于为什么争论的立场不同,我无话可说,但我认为亚瑟的建议是有道理的:

  • 有些函数显然是在集合上运行的(
    map
    reduce
    ,等等)。这些函数倾向于始终将集合作为最后一个参数,这意味着它们可以很好地与
    ->
  • 有些函数不在集合上操作,并且倾向于将最重要的参数(这是一件事吗?)作为第一个参数。例如,当使用
    /
    时,我们希望分子排在第一位。这些函数在
    ->
    时效果最好
问题是-有些函数是不明确的。它们可能接受一个集合并生成一个值,或者接受一个值并生成一个集合。
string\split
就是一个例子(暂时不考虑字符串可能同时被视为单个值或集合的额外混淆).连接/减少操作也可以做到这一点-它们会打乱您的管道

例如,考虑:

(->> (range 1 5)
     (map inc)
     (reduce +)
     ;; at this point we have a single value and might want to...
     (- 4)
     (/ 2))
     ;; but we're threading in the last position
     ;; and unless we're very careful, we'll misread this arithmetic
在这些情况下,我认为像
as->
这样的东西非常有用


一般来说,我认为在集合上操作时使用
->
的指导原则是正确的,否则使用
->
是正确的,只是在这些边界/不明确的情况下,
as->
可以使代码更整洁、更清晰。

通过另一个线程来处理线程表达式并没有错宏,如下所示:

(-> string
    (str/split "\s")
    modification-1
    modification-2
    modification-n
    (->> (str/join "\n")))

(join“\n”(split string“\s”))有什么问题吗?我在两者之间遗漏了一些修改函数。为了清楚起见,添加了它们。为什么?
clojure.string.join
与接受集合的其他函数一致。
(映射f列)(过滤器f列)
@ShannonSeverance嗯,字符串在Clojure中被认为是序列。我想这会把字符串变成部分形式。用括号括起来?你也可以做…(modification-n)(>(str/join“\n”))你确定它能工作吗?在我看来,modification-n的结果将在partial.Love这个新宏中str/join之前被线程化。有一个库可以做到这一点,很高兴看到它出现在
core
中。这比旧方法好得多,并且使代码更易于阅读,因为我不必在阅读时想象缺少的参数。我喜欢线程宏,但他暗中希望通过线程等价的
swap
roll
dup
来操纵参数顺序。啊,好吧。接受这一点是因为它适用于每个函数,并试图找到问题的答案。不过,我想第二个箭头应该是
->
。丹尼尔·尼尔的答案要好得多这是事实,但它没有回答问题。