Open agocke opened 5 years ago
IIRC tail recursive call optimization is guaranteed by JIT: https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8BLAOwwAIBZACjMoQEoBYAKAG82LuLiAzCjQQUAvCIoBGRhQACAdkkBuLj3nUhFOJMbLWAXyA==
@hez2010 Maybe in simple cases like that, but what about with virtual and non-self recursion?
void Func()
{
// ...
FuncVirt();
}
protected virtual void FuncVirt()
{
// ...
Func2();
}
void Func2()
{
// ...
if (x)
{
Func();
}
}
There are a number of instances where it may be clearer to express your algorithm via recursion, especially tail recursion, but unfortunately all recursion in C# currently requires O(n) space for just the call stack, meaning that your algorithm cannot take less than O(n) space.
It is proposed that C# provide a new statement form and a new expression form to allow tail-recursive calls to consume O(1) space.
Syntax and Semantics
The statement form would be
tail return <expr>
, analogous toyield return
, where theexpr
target is required and must be a tail recursive call.The expression form would be
tail <expr>
, where the<expr>
would have the same restrictions as the statement form, and thetail <expr>
expression would only be legal as the expression in an expression-bodied member.Codegen
There is a
tail
instruction in the CLR, but if that instruction is not reliable or desired, the compiler can lower this into agoto
after assigning the new arguments for the recursive call.For instance,
Could be rewritten to
Limitations
Because the compiler cannot reliably rewrite inter-procedural calls, this would only currently be legal for tail-recursive calls. It would not be allowed for e.g., mutually tail recursive calls. If the CLR can reliably perform
tail
calls without significant downsides on all supported platforms, the feature could be broadened from the current specification.