# 15-150: Principles of Functional Programming

# Lecture 4: Recursion and Structural Induction on Lists, Tail Recursion

In the previous lecture, we introduced SML's predefined datatype
`int list` for lists of integers.

An important point is that the list datatype is defined
recursively:

An `int list` is one
of the following (and nothing else):

- Either the empty list
(written
`nil` or `[]`), - or of the form
`x::xs`, with `x : int`
and `xs : int list`.

Last time and today we wrote some functions taking list arguments
and/or returning list values, and we showed how to prove theorems
about lists using structural induction.

We discussed tail recursion, a form of recursion that is somewhat like
the use of loops in imperative programming. This form of recursion is
often used to make functions more efficient.

**Terminology:** A function is *tail
recursive* if it is recursive and if it performs no computations
after any recursive call that it makes. This means in particular that
the function directly returns any value obtained from any recursive
call that it makes. More generally, a function `f` is
said to make a *tail call* to function `g` if calling
`g` is the final computation `f` performs. From that
perspective, a recursive function `f` is tail recursive if any
calls to itself are tail calls.

(Clarifying Comment: If the body of a function contains
multiple locations at which a recursive call occurs, then every one
of those recursive calls must be a tail call in order for the
function to be considered tail recursive.)

**Accumulator arguments** play an important role in
tail recursion. The presence of an accumulator argument in a function
forces us to think carefully about the specification of the function
and to prove corresponding theorems of correctness.

### Key Concepts

- Lists defined recursively
- Correspondence between recursive datatype, recursive function
clauses, and proof by structural induction
- Tail Recursion
- Accumulator argument

(Those notes also discuss two concepts that we have not yet
discussed: datatype declarations and structural induction over trees;
we will see these in the next lecture.)