CS 334
Programming Languages
Spring 2002

Lecture 4

Efficiency

Updating of data structures is based on sharing (where possible):

Ex.: If define

   - fun updatehd newhd (head::tail) = newhd :: tail;
then get sharing:

Safe, because list elt's not updatable!

Simulating iterative programs

Can simulate iterative programs in functional language by making local variables into parameters.

Ex. Obvious recursive def in ML:

   - fun fib 0 : int = 1   
       |  fib 1 = 1   
       |  fib n = fib (n-2) + fib (n-1);
Iterative solution in Pascal - faster!
   Function fastfib (n:integer):integer;   
   val a,b : integer;   
   begin   
      a := 1; b := 1;   
      while n > 0 do   
      begin   
         a := b; b := a + b; n := n-1  (* all done in parallel, else wrong! *)   
      end;   
      fib := a   
   end;

ML equivalent

   fun fastfib n = let    
         fun fibLoop a b 0 = a   
           | fibLoop a b n : int = fibLoop  b (a+b) (n-1)   
     in    
         fibLoop 1 1 n   
     end;   

Proving a functional program correct

Let's see how you can give a proof of correctness of a functional program:

    fun fastfib n : int = 
          let    
            fun fibLoop a b 0 = a   
              | fibLoop a b n : int = fibLoop  b (a+b) (n-1)   
          in 
            fibLoop 1 1 n   
          end;
Prove fastfib n = fib n where
    fun fib 0 = 1   
     |  fib 1 = 1   
     |  fib n = fib (n-2) + fib (n-1);

Let ai = fib i, for all i.

Therefore a0 = a1 = 1, and ai + ai+1 = ai+2 for all i >= 0, by def of fib.

Theorem: For all i, fibLoop ai ai+1 n = ai+n.

Pf by induction on n:

If n = 0, fibLoop ai ai+1 0 = ai = ai+0 by def.

Suppose true for n - 1:

Then

    fibLoop ai ai+1 n = fibLoop ai+1 (ai + ai+1) (n - 1) 
                      = fibLoop ai+1 ai+2 (n - 1)
                      = ai+1+(n-1) = ai+n.
Now
    fastfib n = fibLoop 1 1 n 
              = fibLoop a0 a1 n 
              = a0+n 
              = an
by the Theorem.

Therefore, for all n, fastfib n = fib n.

Similar proofs can be given for other facts, e.g.,

    nlength (append l1 l2) = nlength(l1) + nlength(l2)
where
    fun nlength [] = 0   
      | nlength (h::rest) = 1 + nlength rest
and
    fun append [] l2 = l2   
      | append (h::rest) l2 = h :: (append rest l2)


Back to:
  • CS 334 home page
  • Kim Bruce's home page
  • CS Department home page
  • kim@cs.williams.edu