什么是lazy-ish juxt功能的优点?

时间:2012-04-06 22:24:07

标签: clojure functional-programming lazy-evaluation

在回答a question关于使用相同参数(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'限制其他参数应该在普通的juxt中一样懒惰。

这个juxt真的很懒吗?懒惰的juxt会给表带来什么有用的东西,例如作为其他懒惰函数之间的合成步骤吗?性能(mem / cpu / object count / compilation)的含义是什么? 为什么Clojure juxt用reduce实现并返回一个打破懒惰的向量?

1 个答案:

答案 0 :(得分:1)

是的,由于只调用懒惰的地图,你对juxt的实现是懒惰的。

很难用它现在的形式来调用它,而没有在调用者中实现参数(通过使用apply。所以我改了一点来获取一系列函数:

user> (defn could-be-lazy-juxt
  [funs]
  (fn [& args]
    (map #(apply %1 %2) funs (repeat args))))
#'user/could-be-lazy-juxt

然后定义一个懒惰的函数序列,当它实现时会产生大量的输出

user> (defn loud-seq [len] (take len (map #(do (println "produced a function") %) (cycle [inc dec]))))
#'user/loud-seq

然后使用juxt从这个懒惰的函数序列中创建一个函数

user> (def f (could-be-lazy-juxt (loud-seq 50)))
#'user/f

正如您所看到的那样,列表仍然是惰性的,它会在调用结果函数时实现它的函数列表。

所以我们称之为:

user> (f 1)
(produced a function
produced a function
2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 0)
user> 

我将这样做的理由留给你;)