CSci 450/503: Programming Languages

Recursion Styles

H. Conrad Cunningham

5 September 2017

Acknowledgements: These slides accompany sections 3.3-3.5 (Linear and Nonlinear Recursion, Backward and Forward Recursion, Logarithmic Recursion) from Chapter 3 “Evaluation and Efficiency”" of “Introduction to Functional Programming Using Haskell”.

Advisory: The HTML version of this document may require use of a browser that supports the display of MathML. A good choice as of September 2017 is a recent version of Firefox from Mozilla.

Recursion Styles

Lecture Goals

Linear Recursion

Nonlinear Recursion

Linear vs. Nonlinear

Backward Recursion

Forward Recursion (1)

Forward Recursion (2)

    factIter :: Int -> Int -> Int  -- auxiliary function, two args
    factIter 0 r         = r
    factIter n r | n > 0 = factIter (n-1) (n*r)  -- forward recursive

Tail Recursion (1)

Tail Recursion (2)

    fib2 :: Int -> Int
    fib2 n | n >= 0 = fibIter n 0 1 
        where 
            fibIter 0 p q         = p   -- two accumulators
            fibIter m p q | m > 0 = fibIter (m-1) q (p+q)

Logarithmic Recursion (1)

Logarithmic Recursion (2)

    expt2 :: Integer -> Integer -> Integer
    expt2 b n | n < 0 = error ("expt2 undefined for negative exponent" 
                               ++ show n )
    expt2 b n         = exptIter n 1
        where exptIter 0 p = p
              exptIter m p = exptIter (m-1) (b*p) -- tail recursive

Logarithmic Recursion (3)

Logarithmic Recursion (3)

    expt3 :: Integer -> Integer -> Integer
    expt3 _ n | n < 0 = error ("expt3 undefined for negative exponent"
                               ++ show n )
    expt3 b n         = exptAux n
        where exptAux 0 = 1
              exptAux n
                | even n   = let exp = exptAux (n `div` 2) in -- local
                                 exp * exp       -- backward recursive
                | otherwise = b * exptAux (n-1)  -- backward recursive

Key Ideas

Code

The Haskell code for this seciton is in file EvalEff.hs.