This is possible, and trivial, when self-recursing: A -> A
If you have an A -> B, or A -> [indirect] call, that is not the case.
If you have an A -> B, or A -> [indirect] call, that is not the case.
It's an ugly piece of code, but because of parsers, there is a huge amount of know how on it.
For example, what if those functions are in different modules or libraries? Tail calls are still supposed to work.
g(): a = 1+1; b = 2+a; print(b); return f()
into code that does not allocate stack space and just reuses the frame allocated for g()?