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:

code44

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

code50

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

tex2html_wrap_inline121 Define ``ancestor.''

tex2html_wrap_inline121 Factorial.

tex2html_wrap_inline121 Insertion sort.

tex2html_wrap_inline121 Quick sort.

tex2html_wrap_inline121 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:

code58

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

code62

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

The form

code67

is actually a derived form for

code70

More Recursion on Integers

Fibonacci numbers:

code74

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

Sum up the first 10 integers:

code76

Sum up the first 20 Fibonacci numbers:

code78

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

Recursion on Lists

Computing the maximum of a list of integers:

code81

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.

code83

Insertion sort:

code85

Building Lists

Recursive structures must also be built by recursion:

code89

Remember the key ideas!

The ultimate in useless functions:

code92

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

Nearly as bad:

code94

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:

code96

Multiple base cases

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

code99

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


Andrew P. Tolmach
Thu Apr 10 18:59:09 PDT 1997