**Pragmatics**

Efficiency concerns:

Time

Space (= Time!)

Reasonable assumptions for tracking resource use:

Applying a constructor allocates heap space.

Evaluating a `fn` expression allocates heap space for **free variables**.

Applying a function takes time.

Only recursive applications really matter. But not all recursive applications are equally expensive!

**Costs of Recursion**

Consider this version of the `sum` function:

Or, equivalently,

What's involved in evaluating this function on a large list?

At each recursive call `sum t`, must:

store the value of local variable `h`

store the current pc

pass the argument `t`

jump to the beginning of `sum`

On return, must:

pass back the result value `r`

retrieve the old pc and jump there

restore the value of `h`

Only then can the addition `h+r` be performed.

**Tail Recursion**

Compare this version of `sum`:

Notice that the recursive call to `sum'` is the
**last** thing that happens in the function body.
Such a call is said to be a **tail** call, and `sum'`
is said to be **tail-recursive**.

In performing the tail-recursive call to `sum'`, the same steps
could be performed as before, but this is not necessary.

Because the caller does nothing after the return (except return itself), there is really no need for the recursive call to return control to the caller.

Instead, the callee can return its value directly to the top
of the recursion (the call from `sum`).

So there's no need for the recursive call to save any local variables nor to store the current pc.

In short, a tail-recursive call can be performed just by passing the argument values and then performing a simple jump to the beginning of the called function.

**Tail Recursion and Iteration**

This is in every way much cheaper than an ordinary call. Indeed, it's
no more expensive than jumping to the top of an **iterative** loop
in an imperative language.

In fact, it's essentially the same thing:

**Accumulation Parameters**

The difference between `sum` and `sum'` is that the latter
uses an extra parameter to `accumulate` the result, which is
then returned by the `nil` case.

Adding an accumulation parameter is a common technique for changing non-tail-recursive functions to tail-recursive ones.

Contrast:

The latter also avoids doing expensive append operations.

**Reduce vs. Accumulate**

Recall the general-purpose right-to-left `reduce` function

which computes

`(x op (x op ( (x op a) ...)))`

Note that it is **not** tail-recursive. But the similar
left-to-right **accumulate** function **is**:

which computes

`(( ((a op x ) op x ) ) op x)`

We can always rewrite a `reduce`
as a (perhaps more complicated) **accumulate**. In the special case
where `op` is associative and commutative,
`reduce` and `accumulate` calculate the same thing.

**Auxiliary Parameters**

In general, it is more work to get rid of non-tail recursion in operations over trees. Consider

We can use an accumulator to get rid of one non-tail call (and the append operation) by passing the accumlated flattening of all right-neighbors:

Note that there is still one non-recursive call. We can get rid of it as well,
by adding **another** extra parameter that keeps an explicit stack of left-neighbor
trees to be flattened:

**Continuation functions**

It turns out that we can always rewrite arbitrary recursive algorithms as tail-recursive ones by using explicit stack arguments like this. This is true in an ordinary imperative language too. (It's not clear that doing so will be a ``win,'' however, unless we can also make other improvements-such as getting rid of appends-in the process.)

There's another, remarkable, method by which we can turn
a functional program into one that is completely tail-recursive
using extra arguments of **function** type.

Consider `sum` again:

And this version:

Here `sum'` takes an extra argument `k`,
called a **continuation**, which says ``what to do with the result.''
Although tail-recursive, this program isn't really any more efficient
than the original one. (Any ideas why not?)

Thu May 22 18:29:48 PDT 1997