recursion - Utility to encapsulate tail-call optimisation in JavaScript? -
i've been reading recursive functions , tail call optimisation (tco) in javascript. goal overcome stack overflow in recursive function:
function factorial(n) { function recur(n, acc) { if (n === 0) { return acc; } else { return recur(n - 1, n * acc); } } return recur(n, 1); } factorial(5); // 120 console.log(factorial(4585759)); // maximum call stack size exceeded
i have found how use thunk
, trampoline
overcome stack overflow in recursive function:
let thunk = function (fn) { return function() { let args = array.prototype.slice.apply(arguments); return function() { return fn.apply(this, args); }; }; }; function trampoline(f) { while (f && f instanceof function) { f = f(); } return f; } function factorial(n) { let recur = function(x, n) { if (n === 0) { return x; } else { return thunk(recur)(n * x, n - 1); } }; return trampoline(thunk(recur)(1, n)); } console.log(factorial(5)); // 120 console.log(factorial(4585759)); // infinity
however, didn't way i'm forced write recursive function. found implementations of function named tco
:
function tco(fn) { var active, nextargs; return function() { var result; nextargs = arguments; if (!active) { active = true; while (nextargs) { result = fn.apply(this, [nextargs, nextargs = null][0]); } active = false; } return result; }; }
the function should allow following:
let factorialtoc = tco(function(n) { function recur(n, acc) { if (n === 0) { return acc; } else { return recur(n - 1, n * acc); } }; return recur(n, 1); });
but not working:
factorialtoc(5); // 120 console.log(factorialtoc(4585759)); // maximum call stack size exceeded
is there utility functions encapsulate tco?
you applied tco
function non-recursive factorialtoc
function, not recur
leads stack overflow. should rather be
function factorialtoc(n) { const recur = tco(function(n, acc) { if (n === 0) { return acc; } else { return recur(n - 1, n * acc); } }); return recur(n, 1); }
Comments
Post a Comment