**Recursion**

So far, all the programs we can write will run very quickly! Roughly speaking, the number of steps they take can't be larger than the size of the program.

To obtain the computing power of ordinary languages, or Turing machines, etc.,
we need a way to **repeat** computations.

Most languages support **loops**. SML does have a loop construct:

but this is completely useless in **pure** programs. (Why?)

Pure functional programs use **recursive** functions instead of iteration
to achieve repetition. Crucial difference is that each recursive activation
of a function provides **new** actual parameters to be bound to the function's
formal parameters.

So, the function can compute something different each time it is called!

**Recursion is not hard**

**Recursive** definition is one that mentions the thing being defined
in the body of the definition.

Define ``ancestor.''

Factorial.

Insertion sort.

Quick sort.

Towers of Hanoi.

Key idea: Recursive calls must be on some ``smaller'' or ``simpler'' argument.

Key idea: There must be one or more base cases to terminate the recursion.

Note direct correspondence to **induction**.

**Recursion in SML**

Recursive definitions are introduced by adding the keyword `rec` after
the keyword `val`:

The effect of `rec` is to make sure that the right version of `f`
is used; compare:

The expression on the RHS of a `val rec` **must** be a function (`fn`) expression.

The form

is actually a derived form for

**More Recursion on Integers**

Fibonacci numbers:

Traditional ``for'' loops must be done with recursions.

Sum up the first 10 integers:

Sum up the first 20 Fibonacci numbers:

There's a pattern here: we'll abstract soon...

**Recursion on Lists**

Computing the maximum of a list of integers:

The need to case over a function argument is so common that there is a special derived form that combines functions and case expressions into one, e.g.

Insertion sort:

**Building Lists**

Recursive structures must also be **built** by recursion:

**Remember the key ideas!**

The ultimate in useless functions:

(``I yam what I yam.'' - Popeye)

Nearly as bad:

Remembering to define the base case(s) is crucial for correctness and termination.

Also helps us understand ``how recursion works.''

If the argument is a data constructor, SML helps us remember base cases:

**Multiple base cases**

Problem: Given a list of integers, return the same list with zeroes inserted between each.

``Theorem: All cats are the same color.''

Thu Apr 10 18:59:09 PDT 1997