ATS: Programming with Theorem-Proving/Tail-call and Tail-recursion
Tail-recursion is of crucial importance for programming in ATS.
Suppose that a function foo
calls a function bar
, where foo
and bar
may be the same one. If the return value of the call to bar
is also the return value of foo
, then this call to bar
is often referred to as a tail-call. If foo
and bar
are the same, then this is a (recursive) self tail-call. For instance, there are two recursive calls in the body of the function f91
defined as follows:
fun f91 (n: int): int = if n >= 101 then n - 10 else f91 (f91 (n+11))
The outer recursive call is a self tail-call while the inner one is not.
If each recursive call in the body of a function is a tail-call, then this function is a tail-recursive function. For instance, the following function sum2
is tail-recursive:
fun sum2 (n: int, res: int): int = if n > 0 then sum2 (n-1, n+res) else res
In ATS, the single most important optimization is probably the one that turns a self tail-call into a (local) jump. This optimization effectively turns every tail-recursive function into the equivalent of a loop. Although ATS provides direct syntactic support for constructing for-loops and while-loops, the preferred approach to loop construction in ATS is through the use of tail-recursive functions.