Оптимизация переполнения хвоста ES6

Прочитав описание Dr Rauschmayer в рекурсивной оптимизации хвостового вызова в es6, я с тех пор пытался воссоздать выполнение "нулевого стека" рекурсивной факториальной функции он детализирует.

Используя отладчик Chrome для шага между кадрами стека, я вижу, что оптимизация хвоста не происходит, и создается кадр стека для каждой рекурсии.

Я также попытался проверить оптимизацию, вызвав функцию без отладчика, но вместо этого передав 100000 в факториальную функцию. Это вызывает ошибку "максимального стека", что означает, что она фактически не оптимизирована.

Вот мой код:

const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )

Результат:

Uncaught RangeError: Maximum call stack size exceeded

Ответ 1

V8, движок JavaScript в Chrome, некоторое время поддерживал TCO, но с этого обновленного ответа (ноябрь 2017 года) он больше не работает, и на момент написания этой статьи активная разработка TCO в V8 отсутствует. Планируется. Вы можете прочитать подробности в ошибке отслеживания V8 для него.

Поддержка TCO, похоже, достигла приличного уровня в V8 в какой-то момент, но осталась за флагом по нескольким причинам (проблемы отладки, ошибки). Но затем произошло несколько вещей, не в последнюю очередь, что команда V8 подняла существенные проблемы с TCO и решительно поддержала изменение спецификации, названное синтаксические хвостовые вызовы (STC), которые требуют, чтобы хвостовые вызовы были помечены в исходном коде намеренно (например, return continue doThat();). Однако это предложение стало inactive в июле 2017 года. Также в июле, когда работа TCO не была выполнена, команда V8 удалила код поддержки TCO из источника для TurboFan *, поскольку в противном случае он был бы подвергнут битроту. (Например, стать болью обслуживания и источником ошибок.)

Итак, в настоящее время (ноябрь 2017 года) неясно, что "невидимая" ТШО будет когда-либо в V8, будут ли какие-то НТЦ входить или что. Страница Страница состояния платформы Chrome для этого означает "смешанные" общедоступные сигналы от Mozilla (Firefox/SpiderMonkey) и Microsoft (Edge/Chakra) при поддержке TCO, что Safari поставляется с TCO, и что веб-разработчики "позитивно" относятся к этой функции. Посмотрим, куда мы идем. Если где угодно.

* (TurboFan = текущий передовой JIT-компилятор в V8, теперь они переключились из Full-Codegen [JIT] + коленчатый вал [агрессивная оптимизация JIT] для Ignition [интерпретатор +] и TurboFan [агрессивная оптимизация JIT])

Ответ 2

Команда V8 (Chrome JS engine) пока не внедряет TCO. Это вырвано из самых последних версий (см. Эту ветку).

Из основных браузеров только Safari реализовал эту функцию.

В Node.JS версии 8 и новее TCO недоступен.

Может быть некоторая надежда на внедрение TCO: на недавнем собрании WebAssembly Google и все другие присутствующие группы были нейтральными или позитивными в отношении дальнейшего изучения внедрения TCO.