Охватывает ли ES6 Tail Call Optimization генераторы?

Охватывает ли поддержка ES6 оптимизации хвостовых вызовов хвостовыми вызовами в генераторах?

Предположим, у меня есть этот генератор для целых чисел>= 0:

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

В настоящее время в Chrome и Firefox он добавляет уровень стека к каждому рекурсивному вызову и в конечном итоге приводит к ошибке "Превышен максимальный размер стека вызовов". Будет ли это происходить после полной реализации ES6?

(Я знаю, что могу написать вышеупомянутый генератор итеративно и не столкнуться с ошибкой. Мне просто интересно, будет ли TCO заботиться о рекурсивно определенных генераторах.)

1 ответ

Решение

Когда выполняется вызов функции, в соответствии с разделом Оценка вызова функции,

  1. Пусть tailCall будет IsInTailPosition (thisCall)
  2. Вернуть? EvaluateCall (func, ref, arguments, tailCall)

Вызов будет оцениваться на основе IsInTailPosition результат. И если если мы проверим IsInTailPosition,

  1. Если body - это FunctionBody объекта GeneratorBody, вернуть false.

Таким образом, если тело функции является генератором, оптимизация Tail Call не будет выполнена.

Другие вопросы по тегам