Questions tagged [tail-call]

Tail call is a subroutine call that happens inside another procedure as its final action; it may produce a return value which is then immediately returned by the calling procedure.

The call site is then said to be in tail position, i.e. at the end of the calling procedure. If any call that a subroutine performs, such that it might eventually lead to this same subroutine being called again down the call chain, is in tail position, such a subroutine is said to be tail-recursive, which is a special case of recursion. Tail calls need not be recursive – the call can be to another function – but tail recursion is particularly useful, and often easier to handle in implementations.

Tail calls are significant because they can be implemented without adding a new stack frame to the call stack. Most of the frame of the current procedure is not needed any more, and it can be replaced by the frame of the tail call, modified as appropriate (similar to overlay for processes, but for function calls). The program can then jump to the called subroutine. Producing such code instead of a standard call sequence is called tail call elimination, or tail call optimization. Tail call elimination allows procedure calls in tail position to be implemented as efficiently as goto statements, thus allowing efficient structured programming. In the words of Guy L. Steele "in general procedure calls may be usefully thought of as GOTO statements which also pass parameters, and can be uniformly coded as [machine code] JUMP instructions" – see history for further discussion.

Traditionally, tail call elimination is optional. However, in functional programming languages, tail call elimination is often guaranteed by the language standard, and this guarantee allows using recursion, in particular tail recursion, in place of loops. In such cases, it is not correct (though it may be customary) to refer to it as an optimization. The special case of tail recursive calls, when a function calls itself, may be more amenable to call elimination than general tail calls, when the function may be different.

30 questions
1
vote
0 answers

Tail-calls corrupted when compiled with __attribute__((musttail))

I was working a Lisp interpreter with a 'threaded' design, where it compiles to a VM where each instruction is a C function that calls the next instruction — if the compiler does tail call elimination, then it should only need a jmp between…
Josh Pritsker
  • 46
  • 1
  • 5
1
vote
1 answer

Are tail calls on diverging functions optimized in Rust?

If I have the following functions: fn a() -> ! { b() } fn b() -> ! { loop {} } Does Rust optimize such calls to simple jumps? I have looked at a Playground to show the assembly, but a seems to just callq the b function. Is this always the…
1
vote
1 answer

Is there a way to optimize tail calls in Scala?

I am aware that Scala has optimizations for tail-recursive functions (i.e. those functions in which the recursive call is the last thing executed by the function). What I am asking here is whether there is a way to optimize tail calls to different…
1
vote
3 answers

how to insert in the middle of a list, being tail-call friendly but without hurting performance?

So I have this function which seems to be non-tail-call friendly, right? let rec insertFooInProperPosition (foo: Foo) (bar: list): list = match bar with | [] -> [ foo ] | head::tail -> if (foo.Compare(head)) then …
1
vote
1 answer

luajit can't hook "tail return"

We know Lua has a library function debug.sethook, when any function return, the hook function be called with event "return" or "tail return", but LuaJIT do not hook "tail return". Is there any methods to turn off the specialization of LuaJIT, and…
Joey.Luo
  • 89
  • 5
1
vote
2 answers

Tail calling in Java and C#?

I was reading about Clojure and found a discussion about Java not supporting tail calls, in the current version, and that people were throwing exceptions to simulate tail calling in the JVM, anyways it sounds like people are doing some crazy stuff…
Robert Gould
  • 68,773
  • 61
  • 187
  • 272
1
vote
1 answer

Does every Haskell function do tail calls?

I wondered that every function in Haskell should be tail recursive. The factorial function implemented as a non tail recursive function: fact 0 = 1 fact n = n * fact (n - 1) Every operator is a function too, so this is equivalent to fact 0 = 1 fact…
Karroffel
  • 115
  • 6
1
vote
2 answers

Tail recursion optimization and recursion in Java

I have a question about tail calls optimization, I need to know how this java code behaves: private void doSomething(int v) { inf f = someCalculation(v); if (f < 0) doSomething(v/2); else doSomething(v*2); } This code is a nonsense…
0
votes
1 answer

Why does clang have trouble with optimizing tail calls in destructors?

Here is a simplified singly-linked list, where each node owns the next, along with a function for destroying the list: struct Node { Node* next = nullptr; ~Node() { delete next; } }; void Destroy(Node* head) { delete head; } Clang…
jacobsa
  • 5,719
  • 1
  • 28
  • 60
0
votes
0 answers

How to Optimize Tail Calls in a Scheme Interpreter?

Hello people of the internet, I am working on a project for a class and cannot solve this bug for the life of me. The project is to write a Scheme interpreter in Python. Much of the code was given to me and I had to fill in the rest. I am on the…
WyWyGuy
  • 3
  • 3
0
votes
1 answer

Tail call stack

I'm having trouble understanding the Stack manipulation needed in order to implement Tail call in assembly language. When we have a Tail call to function We basically want to override the current Activation Frame with the Activation Frame of the…
0
votes
0 answers

In tail calls, how do programming languages know what the function call evaluates to?

My question title could be improved, if there's a specific name for what I will talk about let me know. This isn't for a specific language either, all the ones I've used treat function calls as expressions the same. So I've been reading about…
incapaz
  • 349
  • 1
  • 3
  • 11
0
votes
1 answer

F# tail call broken by lack of parentheses

While testing F# tail calls with F# team blog article I found that almost the same code has the same result but different IL although only parentheses in the code differ. Next code is optimized by compiler and I see br.s IL_0000 in the end of IL and…
0
votes
1 answer

Tail recursive exponentiation in Prolog

I'm trying to write the code which get 3 arguments when X is the coefficient, Y is the exponent and R should return the answer. My code till now is - exp(X,0,R):- R is X*X. exp(X,Y,R):- Y1 is Y-1, exp(X,Y1,R). I know it doesn't work. But I can't…
divelner
  • 244
  • 1
  • 2
  • 10
0
votes
2 answers

How to implement tail calls in a custom VM

How can I implement tail calls in a custom virtual machine? I know that I need to pop off the original function's local stack, then it's arguments, then push on the new arguments. But, if I pop off the function's local stack, how am I supposed to…
Puppy
  • 144,682
  • 38
  • 256
  • 465
1
2