在回答有关使用相同参数(A:juxt)映射多个函数的函数的问题时,我想出了一个与 juxt 基本采用相同形式但使用 map 的函数:
(defn could-be-lazy-juxt
[& funs]
(fn [& args]
(map apply funs (repeat args))))
=> ((juxt inc dec str) 1)
[2 0 "1"]
=> ((could-be-lazy-juxt inc dec str) 1)
(2 0 "1")
=> ((juxt * / -) 6 2)
[12 3 4]
=> ((could-be-lazy-juxt * / -) 6 2)
(12 3 4)
我对它的懒惰或性能一无所知,但 REPL 中的时间确实表明正在发生一些懒惰的事情。
=> (time (apply (juxt + -) (range 1 100)))
"Elapsed time: 0.097198 msecs"
[4950 -4948]
=> (time (apply (could-be-lazy-juxt + -) (range 1 100)))
"Elapsed time: 0.074558 msecs"
(4950 -4948)
=> (time (apply (juxt + -) (range 10000000)))
"Elapsed time: 1019.317913 msecs"
[49999995000000 -49999995000000]
=> (time (apply (could-be-lazy-juxt + -) (range 10000000)))
"Elapsed time: 0.070332 msecs"
(49999995000000 -49999995000000)
我确信这个功能并不是那么快(结果的打印“感觉”在两者中都一样长)。对函数执行 'take x' 只会限制评估函数的数量,这可能会限制其适用性,并且通过 'take' 限制其他参数在正常并列中应该同样懒惰。
这并列真的很懒吗?惰性并列是否会给表格带来任何有用的东西,例如作为其他惰性函数之间的合成步骤?性能(内存/cpu/对象计数/编译)有什么影响?为什么 Clojure juxt 用 reduce 实现并返回一个向量,这打破了惰性?