gpt4 book ai didi

recursion - 为什么递归调用不会自动被 recur 取代?

转载 作者:行者123 更新时间:2023-12-02 23:50:14 27 4
gpt4 key购买 nike

在以下(Clojure)SO问题中:my own interpose function as an exercise

接受的答案是这样的:

Replace your recursive call with a call to recur because as written it will hit a stack overflow

(defn foo [stuff]
(dostuff ... )
(foo (rest stuff)))

becomes:

(defn foo [stuff]
(dostuff ...)
(recur (rest stuff)))

to avoid blowing the stack.

这可能是一个愚蠢的问题,但我想知道为什么对 foo 的递归调用不会自动替换为 recur

另外,我又举了另一个例子并写了这个(没有故意使用cond,只是为了尝试一下):

(defn is-member [elem ilist]
(if (empty? ilist)
false
(if (= elem (first ilist))
true
(is-member elem (rest ilist)))))

我想知道是否应该用 recur 替换对 is-member 的调用(这似乎也有效)。

是否存在递归并且特别不应该使用recur的情况?

最佳答案

如果您有尾递归方法,几乎​​没有理由使用recur,尽管除非您处于性能敏感的代码区域只是不会有任何区别。

我认为基本的论点是,显式地显示 recur 可以非常清楚地表明函数是否是尾递归的;所有尾递归函数都使用 recur,并且所有 recur 函数都是尾递归的(如果您尝试使用 recur ,编译器会报错非尾部位置。)所以这是一个审美决定。

recur 还有助于将 Clojure 与对所有尾部调用执行 TCO 的语言(例如Scheme)区分开来; Clojure 无法有效地做到这一点,因为它的函数被编译为 Java 函数,而 JVM 不支持它。通过使recur成为一种特殊情况,希望不会出现过高的期望。

如果编译器是这样设计的,我认为不会有任何技术原因导致编译器无法为您插入 recur,但也许有人会纠正我。

关于recursion - 为什么递归调用不会自动被 recur 取代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7599810/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com