10

Does ES6's support for tail call optimization cover tail calls in generators?

Suppose I have this generator for integers >= 0:

var nums = function* (n) {
    n = n || 0;
    yield n;
    yield* nums(n + 1);
};

Currently, in Chrome and Firefox, it adds a stack level with each recursive call and eventually runs into a "maximum call stack size exceeded" error. Will this still occur once ES6 is fully implemented?

(I know I can write the above generator iteratively and not run into the error. I'm just curious about whether TCO will take care of recursively defined generators.)

andyk
  • 1,628
  • 15
  • 12
  • not sure about generators and TCO in ES6, but according to [this compatibility table](https://kangax.github.io/compat-table/es6/), TCO is not yet implemented in any browsers (as of 5-8-15) which explains (in part) why you're seeing the call stack explode.. – sfletche May 09 '15 at 04:33
  • Just saying, you could remove the first line of your function by giving `n` a default value of `0` (i.e. `function* (n = 0) {`). – Brian McCutchon Aug 06 '16 at 23:19

1 Answers1

8

When a function call is made, according to the section Function call evaluation,

  1. Let tailCall be IsInTailPosition(thisCall)
  2. Return ? EvaluateCall(func, ref, arguments, tailCall)

The call will be evaluated based on the IsInTailPosition's result. And if if we check IsInTailPosition,

  1. If body is the FunctionBody of a GeneratorBody, return false.

So, if the function body is a generator, then Tail Call Optimization will not be done.

aug
  • 11,138
  • 9
  • 72
  • 93
thefourtheye
  • 233,700
  • 52
  • 457
  • 497