javascript-堆栈安全的相互递归,而不会在调用方泄漏实现细节

前端之家收集整理的这篇文章主要介绍了javascript-堆栈安全的相互递归,而不会在调用方泄漏实现细节 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我对clojure的循环/递归蹦床进行了广义化,以便可以与间接递归一起使用:

  1. const trampoline = f => (...args) => {
  2. let acc = f(...args);
  3. while (acc && acc.type === recur) {
  4. let [f,...args_] = acc.args;
  5. acc = f(...args_);
  6. }
  7. return acc;
  8. };
  9. const recur = (...args) =>
  10. ({type: recur,args});
  11. const even = n =>
  12. n === 0
  13. ? true
  14. : recur(odd,n - 1);
  15. const odd = n =>
  16. n === 0
  17. ? false
  18. : recur(even,n - 1);
  19. console.log(
  20. trampoline(even) (1e5 + 1)); // false

但是,我必须在通话侧明确给蹦床打电话.有没有办法像循环/递归那样再次使其隐式?

顺便说一句,这是循环/重复:

  1. const loop = f => {
  2. let acc = f();
  3. while (acc && acc.type === recur)
  4. acc = f(...acc.args);
  5. return acc;
  6. };
  7. const recur = (...args) =>
  8. ({type: recur,args});
最佳答案
显然,由于您希望调用蹦床,因此不能完全跳过它.最简单的事情就是将那些经过抛光处理的调用包装在所需的API中,也许是这样的:

  1. // Utility code
  2. const trampoline = f => (...args) => {
  3. let acc = f(...args);
  4. while (acc && acc.type === recur) {
  5. let [f,args});
  6. // Private implementation
  7. const _even = n =>
  8. n === 0
  9. ? true
  10. : recur(_odd,n - 1);
  11. const _odd = n =>
  12. n === 0
  13. ? false
  14. : recur(_even,n - 1);
  15. // Public API
  16. const even = trampoline(_even);
  17. const odd = trampoline(_odd);
  18. // Demo code
  19. console.log(
  20. even (1e5 + 1)); // false
  21. console.log(
  22. odd (1e5 + 1)); // true

猜你在找的JavaScript相关文章