20-CS-4003-001 Organization of Programming Languages Fall 2017
Actual Programs

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures

Fibonacci Numbers

Java:
   
   import java.math.*;

   public class intro_5 {
      public static void main (String args[]) {
         BigInteger x = new BigInteger("1");
         BigInteger y = new BigInteger("1");
         for (int i=0 ; i < Integer.parseInt(args[0])-2 ; i++) {
	    BigInteger t = x;
	    x = x.add(y);
	    y = t;
         }
         System.out.println(x);
      }
   }

The above can be run as follows:

   prompt> java intro_5 1000
   43466557686937456435688527675040625802564660517371780402481729089536
   55541794905189040387984007925516929592259308032263477520968962323987
   33224711616429964409065331879382989696499285160037044761377951668492
   28875
The answer appears almost instantly. The 1000000th fibonacci number takes 1 minute and 10 seconds to produce. Very little memory was used.
 
Haskell:
   fib n = (1 : 1 : ys) !! (n-1)
      where ys = [ x + y | 
                   x <- 1 : ys | 
                   y <- 1 : 1 : ys]
The list comprehension has three parts! The last part (y <- 1 : 1 : ys) creates a list y of tokens beginning with two 1's followed by whatever ys becomes. The next to last part (x <- 1 : ys) creates a list x of tokens beginning with a single 1 followed by whatever ys becomes. The first part (x+y) adds the lists x and y. The following shows what ys turns out to be (it is initially [] because there is no <token>: in front of the list comprehension):
    y: 1 1 2 3 5 8 ...
    x: 1 2 3 5 8 ...
   ys: 2 3 5 8 ...
The red numbers indicate the list ys values in lists x and y. The !! (n-1) returns the nth number in the list [1,1]++ys.

Run this as follows:

   ghci> fib 1000
   43466557686937456435688527675040625802564660517371780402481729089536
   55541794905189040387984007925516929592259308032263477520968962323987
   33224711616429964409065331879382989696499285160037044761377951668492
   28875
which is output instantly. The 100000th fibonacci number is output almost immediately but the 1000000th number takes more than 10 minutes. Again, memory usage is not a problem. The inferred type of this function is:
   ghci> :t fib
   fib :: Num a => Int -> a
This is changed to Int -> Integer by adding the following line before the code above:
   fib :: Int -> Integer
 
Scheme:
   (define fib (lambda (x y n) (if (<= n 2) x (fib (+ x y) x (- n 1)))))

Run it like this:

   scheme> (f1 1 1 1000)
   ;Value: 43466557686937456435688527675040625802564660517371780402481729089536
   55541794905189040387984007925516929592259308032263477520968962323987
   33224711616429964409065331879382989696499285160037044761377951668492
   28875
The 100000th fibonacci number can be output reasonably fast but the Haskell intrepreter is faster.