为什么reduce不会导致clojure中的堆栈溢出?

Dav*_*vid 0 clojure

假设您有以下代码:

(reduce + 1 (range 1 13000))
Run Code Online (Sandbox Code Playgroud)

这是否不会导致堆栈溢出,因为它没有优化尾部调用?或者说reduce类似于循环?

Ale*_*ler 6

Areduce实际上是集合值的循环。

我说“有效”是因为 Clojure 实际上采用了许多不同的归约实现策略,具体取决于集合的类型。这包括通过first/next进行seq遍历、通过迭代器进行归约,以及知道如何更有效地自归约的集合。

在这种情况下,调用range实际上返回一个LongRange对象,该对象实现了IReduceInit自我归约接口,并且实际上执行了一个紧密do/while循环(在Java中实现)。

可以在最新版本中找到此代码。