← Back to context

Comment by pdpi

13 hours ago

> Tail recursion IME is a bigger foot gun

This is true for some languages, but not all.

E.g. scala has @tailrec annotations, which make it a compile error for the annotated function to not be tail recursive. Clojure doesn't have tail call elimination, but has the `recur` special form for explicit recursion that is guaranteed to not consume any stack space.Rust has reserved the `become` keyword that will eventually guarantee tail call elimination (So pretty similar to Clojure's recur, but I think Rust's version will allow mutual recursion)

Zig goes the whole hog, and has `@call(modifier, fn, args)`, where `modifier` can be things like compile_time, always_tail, always_inline, never_tail, never_inline, and a bunch other desirable guarantees you might want.

> > Tail recursion IME is a bigger foot gun

> This is true for some languages, but not all.

Useless anecdote that tail-recursive can be a foot gun even in Scala.

I did a (screening) job interview at Datadog, they asked for "give the spare change back on that amount of money" exercise (simple variant), "in whichever language you want". I did my implementation in tail-recursive Scala (with the annotation). I ended up trying to explain that tail-recursivity doesn't explode in memory for the rest of the call (and failed)

  • > I ended up trying to explain that tail-recursivity doesn't explode in memory for the rest of the call (and failed)

    I count that as a successful interview – They sent an interviewer who doesn't understand how tail recursion enables tail call elimination, and is either unwilling or unable to listen when is is explained to them. Sounds like the company would be a bad fit for somebody whose go-to approach is to implement the solution that way.