Mind the following function:
function count(n) {
if (n === 0) {
return 0;
} else {
return 1 + count(n - 1);
}
}
It is the simplest recursive function that counts from 0
to N
. Since JavaScript has a small stack limit, that function easily overflows. In general, any recursive function can be converted in one that uses a manual stack and, thus, can't stack overflow; but doing so is complex. Is it possible, for the general case, to convert a JavaScript recursive function in one that uses its own stack, without using a continuation-passing style? In other words, suppose we had written:
const count = no_overflow(function(count) {
return function(n) {
if (n === 0) {
return 0;
} else {
return 1 + count(n - 1);
}
}
});
Is it possible to implement no_overflow
in such a way that this new count
function is equivalent to the old one, except without stack overflows?
Notes:
This is not about tail call optimization, since
no_overflow
should work for non-tail-recursive functions.Trampolining is not helpful since, for the general case, it requires the function to be written in a continuation-passing style, which it isn't.
Writing the function with
yield
doesn't work either for a similar reason: you can'tyield
from inner lambdas.That
no_overflow
would, essentially, work like a stack-free Y-combinator.