It is interesting to note that without tail recursion, functional programming loses most of its charm. Pure functional languages need recursion to express a lot of common structures. Consider a typical pseudo-C event-handling loop:
event = waitForEvent();
/* do something with the event */
Now, the way to write infinite loops in functional programming is through recursion (somewhat inaccurate example):
function handleEvent(event) :
( do something with the event )
Now, as you might remember, every function call needs some memory. Notice that this loop will need more memory for each event it processes; which might be acceptable on most recursive algorithms, but an event-handler which runs without the tail recursion optimization will eventually run out of memory.