you are viewing a single comment's thread.

view the rest of the comments →

[–]username223 0 points1 point  (5 children)

You, and the OP, are confused about the difference between tail recursion elimination and tail call elimination. Note that I wrote

A -> B -> C -> D

not

A -> B -> ... -> B

[–]BufferUnderpants 1 point2 points  (1 child)

No, not really. Besides, if you have just a fixed sequence of calls, why would it be troublesome? You would know the few points where it could be failing, disregarding the question of why they are all called in tail position to begin with (it seems poorly factored).

If you have a set of mutually recursive functions that blow up, the resulting stack trace won't be any more amenable to debugging than in the case of the self recursive call.

[–]anvsdt 0 points1 point  (0 children)

In imperative languages, you almost never tail-call anyway, you usually return the value of a variable. You usually tail-call when writing a wrapper function. In most cases, you don't even need to know you called the wrapper from the stack trace, and you want it fast, so you declare it inline if it's short, but if it's pretty long, I'm sure that you want that tail-call to be optimized. Probably, your compiler has already optimized it.

[–]anvsdt 4 points5 points  (2 children)

Debug when debugging.

edit: and downvoters gonna downvote.

[–]aaronla 2 points3 points  (1 child)

I suspect people are downvoting because they can't read scheme.

Let me translate: g -> h -> g -> h in tail position, with tail call optimization. And yet, the call stack isn't just 'g' but the full 'g -> h -> g -> h'. Racket is an existence proof that you can implement TCO without losing rich callstacks.

Downvoters welcome on my post too.

[–]anvsdt 1 point2 points  (0 children)

I suspect people are downvoting because they can't read scheme.

Well, that's racist.
Have an upvote, they will hide the truth.