Lazy evaluation and memoization in Python computations
We use memoization to cache the computed
results to help speed up the computation of Fibonacci numbers, and
lazy evaluation to create a generator that outputs new Fibonacci
numbers indefinitely.