Skip to content

Instantly share code, notes, and snippets.

@raganwald
Last active February 26, 2017 13:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raganwald/ca196aeb18968f93a4ed6bc52220fb72 to your computer and use it in GitHub Desktop.
Save raganwald/ca196aeb18968f93a4ed6bc52220fb72 to your computer and use it in GitHub Desktop.
Trampolines in ES6
// See http://raganwald.com/2013/03/28/trampolines-in-javascript.html
function trampoline (fn) {
return function trampolined (...args) {
let result = fn.apply(this, args);
while (result instanceof Function) {
result = result();
}
return result;
};
}
// Trampolining a singly tail-call recursive function
const evenTCR = trampoline(
function even (n) {
if (n === 0) return true;
else if (n === 1) return false;
else return () => even(n-2);
}
);
evenTCR(300000003)
//=> false
// trampolining mutually tail-call recursive functions
const evenMR = trampoline(
(n) => {
function even (n) {
return n === 0 ? true : () => odd(n-1);
}
function odd (n) {
return n === 0 ? false : () => even(n-1);
}
return even(n);
}
);
evenMR(1000000001)
//=> false
// Counterexample
const evenStacked = (n) => {
function even (n) {
return n == 0 ? true : odd(n-1);
}
function odd (n) {
return n == 0 ? false : even(n-1);
}
return even(n);
};
evenStacked(1000000001)
//=> RangeError: Maximum call stack size exceeded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment