Javascript 堆栈安全的相互递归,而不会泄漏调用端的实现细节

Javascript 堆栈安全的相互递归,而不会泄漏调用端的实现细节,javascript,recursion,tail-recursion,mutual-recursion,trampolines,Javascript,Recursion,Tail Recursion,Mutual Recursion,Trampolines,我推广了clojure的循环/递归蹦床,使其与间接递归一起工作: const蹦床=f=>(…args)=>{ 设acc=f(…args); while(acc&&acc.type==重复){ 设[f,…args_3;]=acc.args; acc=f(…参数); } 返回acc; }; 常量重复=(…参数)=> ({type:recur,args}); 常数偶数=n=> n==0 ? 真的 :重复出现(奇数,n-1); 常数奇数=n=> n==0 ? 假的 :重复出现(偶数,n-1); con

我推广了clojure的
循环
/
递归
蹦床,使其与间接递归一起工作:

const蹦床=f=>(…args)=>{
设acc=f(…args);
while(acc&&acc.type==重复){
设[f,…args_3;]=acc.args;
acc=f(…参数);
}
返回acc;
};
常量重复=(…参数)=>
({type:recur,args});
常数偶数=n=>
n==0
? 真的
:重复出现(奇数,n-1);
常数奇数=n=>
n==0
? 假的
:重复出现(偶数,n-1);
console.log(

蹦床(偶数)(1e5+1));//false
显然,既然您希望调用蹦床,就不能完全跳过它。最简单的方法就是将那些被践踏的调用封装在您想要的API中,可能类似于这样:

//实用程序代码
常量蹦床=f=>(…args)=>{
设acc=f(…args);
while(acc&&acc.type==重复){
设[f,…args_3;]=acc.args;
acc=f(…参数);
}
返回acc;
};
常量重复=(…参数)=>
({type:recur,args});
//私有实现
常数偶数=n=>
n==0
? 真的
:复发(奇数,n-1);
常数奇数=n=>
n==0
? 假的
:重复出现(_偶数,n-1);
//公共API
常量偶数=蹦床(_偶数);
常数奇数=蹦床(_奇数);
//演示代码
console.log(
偶数(1e5+1));//假的
console.log(

奇数(1e5+1));//true
那么您希望能够传递相互递归的函数,而不让它们知道
recur()
函数吗?不,对不起,我想调用
偶数(1e5+1)
。您有没有看到过?不确定它是否对您有帮助,但那里的代码看起来几乎与您的相同。不,这是不可能的-除了实现您自己的包装函数
even
,该函数调用一个蹦床内部
even
函数。在某些地方,你必须明确地介绍蹦床,没有办法。