This is particularly true because many platforms don't supply tail call optimization, but do supply higher-order function.
For example, Python 3:
import functools
import itertools
def fib(n):
def get_next(i):
a, b = i
return (b, a + b)
a, b = functools.reduce(
get_next,
itertools.repeat(None, n),
(0, 1),
)
return b
This does come out a bit hacky in Python, because Python doesn't have a builtin higher-order function that does something like this: def generate(get_next, c):
while True:
yield c
c = get_next(c)
But many (most?) functional languages have such a function. With that function built in, the code would look something like: import itertools
def fib(n):
def get_next(i):
a, b = i
return (b, a + b)
a, b = next(itertools.islice(
generate(get_next, (0, 1)),
n,
))
return b
Further, most functional languages have a builtin function that gets the nth item in the sequence, which is what `next` and `itertools.islice` are doing above: def nth(seq, n):
return next(itertools.islice(seq, n))
If that were built in also, we get: def fib(n):
def get_next(i):
a, b = i
return (b, a + b)
a, b = nth(generate(get_next, (0, 1)), n)
return b
This gives us some pretty terse code built only of composable builtin pieces, and ostensibly these higher-order functions are written in a lower-level language and highly optimized. This is cleaner than rolling your own tail recursion in a lot of ways.