Clojure中的let绑定函数

3
如果我有一个评估为函数的函数
(defn func1 [c1 c2]
  (fn [x1 x2]
    ...do some stuff with c1 c2 x1))

如果我在 map 或 reduce 中的其他地方使用它,是内联使用更好呢?

(defn func2 [x y z]
  (reduce (func1 x y) z (range 20)))

或者先将其绑定。
(defn func2 [x y z]
  (let [ffunc (func1 x y)]
    (reduce ffunc z (range 20))))

在第一种情况下,我会担心每次通过reduce进行迭代时都会生成一个新的x和y函数。
1个回答

3

在每种情况下,函数调用(func1 x y)的评估只会执行一次。

Clojure中函数调用的求值规则包括对提供作为参数的所有表达式进行求值,然后使用这些值调用函数。

如果定义以下高阶函数:

(defn plus []
  (println "calling plus")
  +)

然后以以下方式调用reduce:

(reduce (plus) [0 1 2 3])

打印了一个单独的calling plus,显示只调用了一次plus函数。

使用let表达式时也会发生同样的情况:

(let [f (plus)]
  (reduce f [0 1 2 3]))

希望能对你有所帮助。

是的,这正是我正在寻找的。 从来没有想过用副作用来测试它。 谢谢。 - Jason Ozias
请注意,实例化函数通常是很便宜的,因此即使分配了多个函数也不会有太大问题。显然,您可以构建昂贵的函数,但这并不像每次都需要重新编译函数一样(我提到这一点是因为闭包的新手经常认为它们每次构建时都会被编译)。 - amalloy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接