recursion - "recursion"、 "a non-terminating procedure that happens to refer to itself"和 "repeated scheduling"之间有什么区别?

标签 recursion language-agnostic scheduling procedure

此问题旨在作为消除描述性术语“递归”或“递归”歧义的规范问题/答案。在适用的范围内,“碰巧引用自身的非终止过程”和“重复调度”。


JavaScript的定义和区别是什么

  1. “递归”;
  2. “一个碰巧引用自身的非终止过程”;和
  3. “重复调度”

我经常看到当函数重复调用自身时使用术语“递归”,尽管 JavaScript 中“递归”的明确定义是什么? ?

我很少看到在描述函数模式时使用的术语“碰巧引用自身的非终止过程”或“重复调度”;通常,“递归”或“递归”用于描述一种模式,其中在函数调用体内,对开始该过程的原始函数进行函数调用。

什么时候“递归”不适用于特定的函数模式; “递归”、“碰巧引用自身的非终止过程”和“重复调度”之间的明确定义和区别是什么?

最佳答案

递归

I often see the term "recursion" used when a function repeated calls itself, though what is the unambiguous definition of "recursion" in JavaScript?

这个定义看起来不错,但是函数不必直接调用自身来递归,它的执行只需要导致它被再次调用。函数不直接调用自身的递归示例如下:调用 A(); 会调用 B();,而 B(); 又会调用 C(); 再次调用 A();

重复调度

像这样的函数使用重复调度:

function A ( foo ) {
  var bar;
  setTimeout( A, 0 );
  console.log( 'hello' );
}

它不是递归的,因为 A 不会在同一调用堆栈上重复调用。当当前的调用堆栈完成时(这意味着“hello”将被记录)并且在事件循环中再次调用 A 之前没有其他任何事情,A 将被调用。除了同步代码和异步代码之间的区别之外,这里的重要区别在于,一次只有一份 foobar 副本,并且调用堆栈不是“t 不断增长,因此不会出现内存或超出最大调用堆栈大小的错误,而对于使用递归的版本,则会出现这种情况:

function A ( foo ) {
  var bar;
  A();
  console.log( 'hello' );
}

在这种情况下,“hello”将永远不会被打印,因为 A 在到达日志语句之前调用自身。

引用自身的非终止过程

非终止过程只是一个无限循环。引用自身有点没有意义:

function A ( ) {
    // Never terminates
    while ( true ) {
        // If A() is called here, or before
        // the loop you have infinite 
        // recursion and a stack size error
    }
    // If, instead, A() is called here,
    // you just have an infinite-loop,
    // since this statement is never reached
}

关于recursion - "recursion"、 "a non-terminating procedure that happens to refer to itself"和 "repeated scheduling"之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41292992/

相关文章:

c - nptl SIGCONT 和线程调度

c++ - 任务委托(delegate)调度器

Haskell 排列库函数 - 请澄清一下?

java - 回文程序,无法终止循环,欧拉计划 #4

python - 为什么在递归函数中计数器没有重置为 0?

algorithm - 绘制一个具有特定像素数的圆

algorithm - 如何改进这个动态规划解决方案(算法优化)

找到包含所有项目的最少标签数量的算法?

java - 使用 java.util.timer 与 Quartz 进行调度的优缺点?

python - 使用递归的生成器对象