Javascript 如何使延迟嵌套函数调用结构堆栈安全?

Javascript 如何使延迟嵌套函数调用结构堆栈安全?,javascript,recursion,functional-programming,stack-overflow,composition,Javascript,Recursion,Functional Programming,Stack Overflow,Composition,堆栈安全递归有时会产生延迟的嵌套函数调用树,一旦计算,可能会耗尽堆栈: const compn=fs=>//非递归以保持简单 减少((f,g)=>comp(f)(g),x=>x); const compn\ufs=>x=>//非递归以保持简单 fs.reduce((x,f)=>f(x,x); 常数comp=f=>g=>x=>f(g(x)); 常数inc=x=>x+1; 常数fs=数组(1e5).fill(inc); 试试{compn(fs)(0)} 捕获(e){ 控制台日志(e.message

堆栈安全递归有时会产生延迟的嵌套函数调用树,一旦计算,可能会耗尽堆栈:

const compn=fs=>//非递归以保持简单
减少((f,g)=>comp(f)(g),x=>x);
const compn\ufs=>x=>//非递归以保持简单
fs.reduce((x,f)=>f(x,x);
常数comp=f=>g=>x=>f(g(x));
常数inc=x=>x+1;
常数fs=数组(1e5).fill(inc);
试试{compn(fs)(0)}
捕获(e){
控制台日志(e.message);
}
控制台日志(compn_fs)(0))使
comp(inc)(comp(inc)(comp(inc)(…))
堆栈安全的一种方法是通过具体化延续来进一步推迟执行:

constcont=k=>({tag:“Cont”,k});
常数compk=f=>g=>x=>
连续(k=>k(f(g(x));
常数compn=fs=>
减少((f,g)=>compk(f)(g),x=>x);
常数id=x=>x;
常数inc=x=>x+1;
const postRec=cont=>{
做{
cont=cont.k(id);
}while(cont&&cont.tag==“cont”)
返回控制;
};
常数fs=数组(1e5).fill(inc);
常量main=compn(fs)(0);
console.log(

postRec(主要))你所说的“较少限制的方式”是什么意思?
compn
在什么意义上是有限的?好吧,
compn
是急切的,它不一定会产生递归数据结构,也就是说,更好的措辞应该是
compn
对于FP来说不太自然。无论如何,这些数据结构似乎是最后一个我无法用堆栈交换堆的场景。不过,在某些情况下,使用这样的结构似乎是有益的,因此,据我所知,其他人解决了这个问题。不幸的是,我无法复制这个解决方案,因为我破译Scala代码的能力有限。
compn\uuu
函数是什么意思?另外,
compn\uu
函数在什么意义上不产生递归数据结构?在我看来,
∀(财政司司长)。复合材料(fs)≡ 组件(fs)
模块堆栈安全。因此,如果
compn\uu
没有生成递归数据结构,那么
compn
也不会生成递归数据结构。最后,即使它没有生成递归数据结构,那“FP不太自然”是怎么回事?顺便问一下,在你链接到作者的文章中,作者使用自由单子来构建计算的AST,而不是构建实际的计算。通过这样做,他用程序堆栈交换堆。然后,他为AST创建一个堆栈安全的解释器。因为堆的大小远远大于程序堆栈的大小,所以不会出现堆栈溢出。在您的特定情况下,
compn
会导致堆栈溢出,因为它会创建大量计算。但是,
compn\uu
不会导致堆栈溢出,因为它使用列表表示法为堆交换堆栈