Software developers in functional programming languages have been told that tail-recursive calls are better than non-tail-recursive ones. A classic example in textbooks is the tail-recursive factorial function (written in F#)
let rec faci n r =
if n = 0 then r else faci (n-1) (r * n)
versus its non-tail-recursive counter-part.
let rec facr n =
if n = 0 then 1 else n * facr(n-1)
It is relatively clear that faci
above does not need an extra stack frame when calling itself as facr
would do. But I am looking for a more vivid example, preferable in F#, from which one can demonstrate why tail-recursive-functions are better than non-tail-recursive ones. Ideally, the improvement can be visualized, e.g., with a memory profiler, or by printing some debugging info. Any idea about such an example?