Derivative example, GCD example, Ackerman's function example

One common mathematical problem is to find the slope of some function
*f* at some point *x*. Given *f*, its
*derivative* *f'* is a function such that *f'(x)*
is the slope of *f* at *x*.
Determining the derivative of a function exactly (symbolically)
is somewhat difficult, and part of calculus.
Calculating an approximation of the derivation is much simpler, and
what we'll do.

Consider the following picture:

**To do:**

- Develop the program
; deriv-at-point : (num -> num) num num -> num (define (deriv-at-point f x eps) ...)

- Develop the program
; deriv : (num -> num) -> (num -> num) (define (deriv f) ...)

choosing an appropriately small constant value of*eps*.

GCD (Greatest Common Divisor) is a common mathematical problem. Given two positive natural numbers, what is the largest (positive) natural number which is a divisor for both inputs? The benefit for us is that it provides a good example of the tradeoffs between structural recursion and generative recursion.

A structurally recursive version is rather straightforward -- count down
until you find a numbers that divides both inputs.
**Q:** What should we count down from?
**Q:** Why does this find the *greatest* common divisor?
Here's the code:

;; gcd-structural : N[>=1] N[>=1] -> N[>=1] ;; find the greatest common divisor of the two inputs ;; Examples: ;; (gcd 6 25) = 1 ;; (gcd 18 24) = 6 ;; based on structural recursion (define (gcd-structural n m) (local (; divides? : N N -> boolean ; returns whether i divides n with zero remainder (define (divides? n i) (zero? (remainder n i))) ; first-divisor-<= : N[>=1] -> N[>=1] ; find the greatest common divisor of m and n ; which is less than or equal to i (define (first-divisor-<= i) (cond [(= i 1) 1] [else (cond [(and (divides? n i) (divides? m i)) i] [else (first-divisor-<= (sub1 i))])]))) (first-divisor-<= (min m n))))

A generative recursive version devised by Euclid requires a "Eureka!".
**To do:** Look at the following and figure out what it does.
**Q:** Why does this work?

;; gcd-generative : N[>=1] N[>=1] -> N[>=1] ;; find the greatest common divisor of the two inputs ;; Examples: ;; (gcd 6 25) = 1 ;; (gcd 18 24) = 6 ;; based on generative recursion (define (gcd-generative n m) (local (; euclid-gcd : N N -> N ; find the greatest common divisor of the two inputs ; assume that larger >= smaller (define (euclid-gcd larger smaller) (cond [(= smaller 0) larger] [else (euclid-gcd smaller (remainder larger smaller))]))) (euclid-gcd (max m n) (min m n))))

The advantage of the structural version is obvious -- it is easier to
understand.
**To do:**
To see the advantage of the generative version, guesstimate how many
recursive calls each version takes to find the answer.
Try out your idea on some more examples, including some larger ones, such as

(gcd-structural 101135853 45014640) (gcd-generative 101135853 45014640)

Here's the definition of a strange numerical function on natural numbers, called Ackerman's Function:

A(m,n) = 0, if n=0 = 2n, if n>0 and m=0 = 2, if n=1 and m>0 = A(m-1,A(m,n-1)), if n>1 and m>0Note that this definition is not structurally recursive. (In fact, it

**To do:**

- Write a Scheme program for this function.
- Try it out on some inputs.
Warning: Try
*very small*inputs first, because the result gets very big very fast.

This function isn't very useful, except as a function that grows faster than probably any one you've seen before. (In technical jargon, the function is not primitive recursive.)