Tail-call optimization, also called tail-call elimination, implements eligible recursive calls without allocating a new call-stack frame for each iteration. A recursive call is in tail position when the caller returns its result directly and performs no further work. section 2.3.1
Factorial as a loop
A factorial helper carries the remaining number and accumulated result: it returns the accumulator at the base case and calls go(n - 1, n * acc) otherwise. Because that recursive call is the final operation, Scala can compile the recursion like a while loop. Changing it to 1 + go(...) would require work after the call and would no longer be tail-recursive. section 2.3.1
Direct tail recursion handles self-recursive loops, but deeply composed functions can still overflow the stack. Trampolining represents computation as TailRec values and interprets them with a tail-recursive run method, trading some speed for predictable stack usage. section 13.3.2


