Description
The current Go language does not support tail calls, because they affect runtime.Callers
and stack backtraces and the like. Because runtime.Callers
in particular must be predictable for Go programmers, adding tail calls to the language would require a precise specification of exactly when they do and do not occur. Since people may sometimes not want them, there would have to be a way to avoid a tail call that would otherwise occur.
That said, people do want tail calls: #15304, #16798. The Alef language had a become
statement, documented as follows (from http://doc.cat-v.org/plan_9/2nd_edition/papers/alef/ref):
The become statement transforms the execution of the current function into the calculation of the expression given as its argument. If expression is not itself a function call, then it must have the same type as the return value of the caller and the behavior is analogous to a return statement. If, however, it is a function call, then it need only have the same return type; the argument list may be different. When a function P executes a become whose expression is a call of Q, the effect is exactly as if the caller of P had instead called Q with the appropriate arguments from P. In particular, the stack frame for P is overwritten by the frame for Q; functions that invoke one another with become will execute in constant stack space.
This proposal is to implement a become
statement with these semantics in Go. The definition would be slightly changed to permit either a list of expressions or a single function call.