Одной из новых функций ES2015 (ES6) являются правильные хвостовые вызовы (PTC). Несмотря на то, что это указано в первой строке Таблицы совместимости ES6, еще не многие браузеры/среды выполнения реализуют это. Среди них Safari 10, выпущенный в прошлом месяце, который включает поддержку PTC.
PTC по библиотеке
Около четырех лет назад я разработал библиотеку под названием continuation.js. Это поддерживает PTC, преобразовывая код JavaScript, который имеет рекурсивные хвостовые вызовы, в код JavaScript, устраняя эти рекурсивные хвостовые вызовы. Моей мотивацией было написать код JavaScript, такой как Scheme, а для этого требуется PTC. Однако преобразование является дорогостоящим, а результирующий код не очень эффективен и быстр. Итак, я с нетерпением жду встроенной поддержки PTC.
Давай попробуем
Вы можете просто попробовать запустить код в консоли Web Inspector. Единственное, что нужно учитывать, это то, что он должен запускаться в режиме скрипта [1].
function fact(x) {
'use strict';
function fact_tail(x, r) {
if (x === 0) {
return r;
} else {
return fact_tail(x — 1, x * r);
}
}
return fact_tail(x, 1);
}
Выше приведена функция для вычисления факториала.
> fact(100000) VM212:2 Uncaught RangeError: Maximum call stack size exceeded(…)
Это выше результат запуска в Chrome 53.
> fact(100000) Infinity
Выше показан результат в Safari 10. Хотя результат Infinity совсем не интересен, расчет завершен без ошибки размера стека.
Ниже приведен еще один пример, который называется «взаимная рекурсия».
function isEven(x) {
'use strict';
if (x === 0) {
return true;
} else {
return isOdd(x - 1);
}
}
function isOdd(x) {
'use strict';
if (x === 0) {
return false;
} else {
return isEven(x - 1);
}
}
// the results follow:
[In Chrome 53]
> isOdd(1234567)
VM3306:10 Uncaught RangeError: Maximum call stack size exceeded(…)
[In Safari 10]
> isOdd(1234567)
true
Опять же, приведенный выше пример не очень причудлив, но дело в том, не сработает ли он с ошибкой размера стека или нет.
Резюме
Ну, я просто хотел проверить, действительно ли Safari 10 выполняет мои старые примеры, и результат успешен. В будущем возможные темы о PTC могут касаться сравнения производительности и практического использования.