javascript - ES6 Tail Recursion Optimization Stack Overflow
ecmascript-6 stack-overflow (2)
Después de leer la descripción del Dr. Rauschmayer de la optimización recursiva de llamadas de cola en es6, desde entonces he estado tratando de recrear la ejecución ''zero-stack'' de la función recursiva factorial que detalla.
Al usar el depurador de Chrome para pasar de un marco de pila a otro, veo que la optimización de la cola no está ocurriendo y que se está creando un marco de pila para cada recursión.
También intenté probar la optimización llamando a la función sin el depurador, pero pasando 100000
a la función factorial. Esto arroja un error de "pila máxima", lo que implica que, de hecho, no está optimizado.
Aquí está mi código:
const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )
Resultado:
Uncaught RangeError: Maximum call stack size exceeded
El equipo V8 (motor JS de Chrome) no está implementando TCO, por el momento. Está arrancado de las versiones más recientes ( mira este hilo ).
De los principales navegadores, solo Safari implementó la función .
En Node.JS versión 8 y posterior, TCO no está disponible .
Puede haber cierta esperanza de que se implemente el TCO: en una reunión reciente de WebAssembly , Google (y todos los otros grupos presentes) fueron neutrales o positivos en la exploración de la implementación de TCO.
V8, el motor de JavaScript en Chrome, tenía compatibilidad con TCO por un tiempo, pero a partir de esta respuesta actualizada (noviembre de 2017) ya no funciona y al momento de escribir esto, no hay desarrollo activo en TCO en V8, y ninguno está planeado. Puede leer los detalles en el error de seguimiento de V8 .
El soporte de TCO parece haber alcanzado un nivel decente en V8 en un punto, pero se mantuvo detrás de una bandera por varias razones (problemas de depuración, errores). Pero sucedieron varias cosas, entre otras cosas, que el equipo V8 planteó problemas importantes con TCO y apoyó firmemente un cambio de especificación llamado llamadas sintácticas de cola (STC) que requeriría que las llamadas return continue doThat();
intencionalmente en el código fuente (por ejemplo, return continue doThat();
). Sin embargo, esa propuesta quedó inactiva en julio de 2017. También en julio, sin que se realizara ningún trabajo de TCO, el equipo de V8 eliminó el código para admitir TCO de la fuente de TurboFan *, ya que de lo contrario estaría sujeto a bitrot. (Por ejemplo, convertirse en un dolor de mantenimiento y fuente de errores).
Por lo tanto, actualmente (noviembre de 2017) no está claro si el TCO "invisible" estará en V8, si algún tipo de STC entrará, o qué. La página de estado de la plataforma Chrome para esto indica señales públicas "mixtas" de Mozilla (Firefox / SpiderMonkey) y Microsoft (Edge / Chakra) para respaldar TCO, que Safari envía con TCO y que los desarrolladores web son "positivos" con la característica. Veremos a dónde vamos desde aquí. Si en cualquier lugar.
* (TurboFan = el actual compilador JIT de vanguardia en V8, ahora cambiaron de Full-Codegen [JIT] + Crankshaft [optimizing agresivo JIT] a Ignition [intérprete +] y TurboFan [agresivo JIT de optimización])