What practical patterns are enabled by TCO in C? My impression is that every tail call can written as a loop much more naturally. Tail calls are important in functional languages where you don't have mutable loop variables.
And imo they are an ugly hack even there - one of the few core constructs where its readily apparent you're not programming an abstract machine but a real, and limited computer. For example the most natural way to write factorial:
let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1)
is not tail recursive, and will overflow if the compiler fails to optimize.
And imo they are an ugly hack even there - one of the few core constructs where its readily apparent you're not programming an abstract machine but a real, and limited computer. For example the most natural way to write factorial:
is not tail recursive, and will overflow if the compiler fails to optimize.