我有以下代码失败,出现以下错误:
RuntimeError:超出最大递归深度
我试图重写它以允许尾递归优化(TCO).我相信如果发生TCO,这段代码应该是成功的.
def trisum(n, csum):
if n == 0:
return csum
else:
return trisum(n - 1, csum + n)
print(trisum(1000, 0))
Run Code Online (Sandbox Code Playgroud)
我是否应该断定Python不执行任何类型的TCO,或者我只是需要以不同的方式定义它?
仅仅因为函数是第一类对象,有闭包和高阶函数,Javascript是否应该被称为函数式编程语言?我认为它缺少的主要功能是纯函数,并且它不像其他函数式语言那样"感觉",比如lisp(虽然这不是一个很好的理由,它不是一个功能性的语言......)
我一直试图Tail call optimization在JavaScript的上下文中理解并编写了下面的递归和尾递归方法factorial().
递归:
function factorial (n) {
if (n < 2) {
return 1;
} else {
return n * factorial(n-1);
}
}
Run Code Online (Sandbox Code Playgroud)
尾递归:
function factorial (n) {
function fact(n, acc) {
if (n < 2) {
return acc;
} else {
return fact(n-1, n * acc);
}
}
return fact(n, 1)
}
Run Code Online (Sandbox Code Playgroud)
但我不确定tail-recursive该函数的版本是否会被JavaScript编译器优化,因为它是在Scala等其他语言中完成的.有人可以帮我解决这个问题吗?
我喜欢的JavaScript到目前为止,并决定使用Node.js的为我的发动机的部分原因是因为这个,它声称的Node.js提供TCO.但是,当我尝试使用Node.js运行此代码(显然是尾部调用)时,会导致堆栈溢出:
function foo(x) {
if (x == 1) {
return 1;
}
else {
return foo(x-1);
}
}
foo(100000);
Run Code Online (Sandbox Code Playgroud)
现在,我做了一些挖掘,我找到了这个.在这里,似乎我应该这样写:
function* foo(x) {
if (x == 1) {
return 1;
}
else {
yield foo(x-1);
}
}
foo(100000);
Run Code Online (Sandbox Code Playgroud)
但是,这给了我语法错误.我试过它的各种排列,但在所有的情况下,Node.js的似乎不满的东西.
基本上,我想知道以下内容:
yield东西在Node.js中如何运作?我向所有人道歉,因为以前版本的这个模糊不清.有人决定对这个新女孩表示同情并帮我改写这个问题 - 这是一个我希望能够解决问题的更新(并且,感谢迄今为止所有那些慷慨解答的人):
问题
我是Uni的第一年,我是一名新的计算机科学专业的学生.对于我的算法类的最终项目,我们可以选择我们想要的任何语言,并实现一种"细化"/"效率"算法,该算法在本地(内部?)用另一种语言找到,但在我们选择的语言中缺失.
我们刚刚在课堂上研究了递归,我的教授简要地提到JavaScript没有实现Tail Recursion.从我的在线研究中,新的ECMA脚本6规范包含此功能,但它目前不在任何(/大多数?)JavaScript版本/引擎中?(对不起,如果我不确定哪个是......我是新来的).
我的任务是为缺少的功能提供2个(编码)WORK AROUND的选项.
所以,我的问题是......是否有人,比我更聪明,更有经验,对我如何实现以下方面有任何想法或例子:
解决了缺乏尾递归优化?
截至2019年2月71.0.3578.98在Mac上的Chrome版本中,以下程序 Uncaught RangeError: Maximum call stack size exceeded error.的计数为16516。
const a = x => {
console.log(x)
a(x + 1)
}
a(1)
Run Code Online (Sandbox Code Playgroud)
我已经做了很多Google搜寻工作,但找不到任何讨论Chrome或其他浏览器对尾部呼叫优化(TCO)支持或将来实现它的计划的文章。
我的两个问题是:
我发现的帖子大多是旧的(2016年或更早的版本)或令人困惑。例如https://www.chromestatus.com/feature/5516876633341952
你有一个递归函数,如:
Blah.prototype.add = function(n) {
this.total += n;
this.children.forEach(function(child) {
child.add(n);
});
};
Run Code Online (Sandbox Code Playgroud)
是child.add()尾巴吗?如果不能这样写的话呢?
var recurse = function(steps, data, delay) {
if(steps == 0) {
console.log(data.length)
} else {
setTimeout(function(){
recurse(steps - 1, data, delay);
}, delay);
}
};
var myData = "abc";
recurse(8000, myData, 1);
Run Code Online (Sandbox Code Playgroud)
这段代码让我烦恼的是我传递了一个字符串 8000 次。这会导致任何类型的内存问题吗?
另外,如果我使用 node.js 运行此代码,它会立即打印,这不是我所期望的。
作为标题,为什么requestAnimationFrame递归不会占用内存.这篇帖子说V8引擎没有优化tail call,所以我想我一定错过了什么.是因为浏览器背后有什么东西吗?或者V8支持优化tail call?
这是MDN的例子:
function step(timestamp) {
var progress = timestamp - start;
d.style.left = Math.min(progress/10, 200) + "px";
if (progress < 2000) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
Run Code Online (Sandbox Code Playgroud) 我最近在Haskell中了解了尾部调用优化.我从以下帖子中了解到这不是javascript的一个功能:
是否有一些固有的javascript设计使得尾调用优化特别困难?为什么这是像haskell这样的语言的主要特征,但现在才被讨论作为某些javascript引擎的特性?
javascript ×9
recursion ×4
node.js ×2
v8 ×2
algorithm ×1
chromium ×1
firefox ×1
optimization ×1
python ×1
stack ×1
terminology ×1