In case someone is looking for a JavaScript solution:
function _fib(n, left, right) {
switch (n) {
case 0: return 0
case 1: return right
default: return _fib(n - 1, right, left + right)
}
}
function fib(n) {
return _fib(n, 0, 1)
}
That runs in O(n) time and O(1) space with tail call optimization.