简体   繁体   English

简单的尾调用优化,用于递归的while循环样式函数

[英]Simple tail-call optimization for recursive, while-loop style functions

I have a simple function: 我有一个简单的功能:

const stackOverflow = (n = 0) =>
  n === 10000 ? 'cool' : stackOverflow(n + 1)

https://jsfiddle.net/dsso9pg6/ https://jsfiddle.net/dsso9pg6/

When I run this, I hit a "Maximum call stack size exceeded" error. 运行此命令时,出现“超出最大调用堆栈大小”错误。 I've read that these sorts of recursive functions can be written differently to avoid this issue in the call stack (something to do with "tail-call optimization"...), but I don't quite see where the issue lies. 我已经读到可以对这些递归函数进行不同的编写,以避免调用栈中出现此问题(与“尾调用优化”有关)……但我不太清楚问题出在哪里。

How would I keep this same recursive function structure while avoiding the error? 在避免错误的同时,如何保持相同的递归函数结构?

Edit: Or is this already tail-call optimized? 编辑:或者这已经优化了? (I was seeing the error in Node.js 8.6 and Chrome 61, but Safari 11 doesn't complain and returns "Cool.") (我在Node.js 8.6和Chrome 61中看到了错误,但Safari 11并没有抱怨并返回“ Cool”。)

You got it right, the while-loop in procedural programming can be replaced by recursion in functional programming paradigm. 没错,过程编程中的while循环可以用函数式编程范式中的递归代替。 Hence, a technique called "tail-call optimization" is invented in some functional programming languages (Haskell for example) to deal with long call stacks in these scenarios. 因此,在某些功能编程语言(例如Haskell)中发明了一种称为“尾调用优化”的技术,用于处理这些情况下的长调用堆栈。

The maximum call stack in javascript also depends on the runtime environment: for example, it's 30000 in my browser but could this could vary. javascript中的最大调用堆栈还取决于运行时环境:例如,在我的浏览器中为30000,但这可能会有所不同。 So your code works fine in my browser and not throw an error. 因此,您的代码在我的浏览器中可以正常工作,并且不会引发错误。 But the idea is that there is an upper limit and tail-call optimization could eliminate that. 但是这个想法是有一个上限的,而尾部调用优化可以消除这种情况。

However, tail-call optimization is a feature supported on language engine level and works in the background rather than a feature that we can use. 但是,尾部呼叫优化是语言引擎级别支持的功能,并且在后台运行,而不是我们可以使用的功能。 And unfortunately, javascript is not truly an FP language so it does not support this feature yet. 不幸的是,javascript并不是真正的FP语言,因此它尚不支持此功能。 Hopefully, when ES6 is finalized we can have this cool feature and use functional programming to its full extent. 希望在ES6完成后,我们可以拥有这个很酷的功能,并充分利用函数式编程。

Edit: You can check whether your runtime environment support TCO here (look like Safari already supported it) 编辑:您可以在此处检查运行时环境是否支持TCO(看起来Safari已经支持它了)

https://kangax.github.io/compat-table/es6/ https://kangax.github.io/compat-table/es6/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM