Clojure:pvalues与pcalls

Dav*_*ood 4 parallel-processing multithreading clojure concurrent-programming

我正在阅读"Clojure的喜悦",以及关于paralellization,功能和部分的部分pvalues,pmappcalls简要介绍了如何使用每个部分.下面是给出的例子pvaluespcalls:

(defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)

(pvalues
  (sleeper 2 :1st)
  (sleeper 3 :2nd)
  (keyword "3rd"))

(pcalls
  #(sleeper 2 :1st)
  #(sleeper 3 :2nd)
  #(keyword "3rd"))
Run Code Online (Sandbox Code Playgroud)

我理解两者之间的技术差异 - pvalues需要计算可变数量的"值",而pcalls并行地调用"任意数量的不带参数的函数".在这两种情况下,都会返回结果的延迟序列.

我的问题基本上是,你何时会使用一个与另一个?似乎唯一的语义差异是你#在每个参数之前粘贴一个pcalls,将它变成一个匿名函数.因此,纯粹从保存击键和使用更简单的代码的角度来看,使用它会不会更有意义pvalues?- 如果是这样,为什么甚至有pcalls功能?

我得到了pcalls,您可以替换一个引用函数的符号,但如果您想使用这样的函数pvalues,您可以将函数放在括号中,以便调用它.

我只是有点困惑,为什么Clojure有这两个相似的功能.有什么可以用一个而不是另一个吗?一些人为的例子可能会有所帮助.

Art*_*ldt 6

pvalues是pcalls的一个方便宏,但因为宏不是第一类,所以它不能以函数的相同方式组合或传递.这是一个只有pcalls工作的例子:

user> (defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)
#'user/sleeper

user> (def actions [#(sleeper 2 :1st) #(sleeper 3 :2nd) #(keyword "3rd")])
#'user/actions

user> (apply pcalls actions)
(:1st :2nd :3rd)

user> (apply pvalues actions)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/pvalues, compiling:(NO_SOURCE_PATH:1:1)
Run Code Online (Sandbox Code Playgroud)

在clojure中设计API时,重要的是不要限制用户只通过宏与您的库交互,因为这样就会受到诸如此类的限制.