Last active
February 26, 2017 13:32
-
-
Save raganwald/ca196aeb18968f93a4ed6bc52220fb72 to your computer and use it in GitHub Desktop.
Trampolines in ES6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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