Wednesday 15 August 2012

Applicative Order Evaluation in Scheme

Arguments to functions can be expressions which are to be evaluated inorder to pass values to function. There are two models of evaluation of arguments to functions. Applicative order and normal order evaluation. In normal order evaluation, not all the arguments are to be evaluated. the evaluation of each argument is delayed until it is necessary. Its a lazy evaluation technique. But in the case of applicative order evaluation all arguments are evaluated regardless of the need.
for example consider function "checkrange" which accepts two parameters x and y, then returns true if x coming under the range 0 to y.

(define (checkrange x y)
    (if (< x 0)
        false
        (if (> x y)
            false
            true)))


Here we have two conditions ,where the second is checked only if the first condition fails. Also the value y is used only then.

If we call this function this way 

(checkrange -15 (/ 100 0))

Since x value less then 0 first check satisfies and function should return a #f (boolean false value) and second argument is not evaluated in case of normal order evaluation. But in scheme this would cause error since it perform application order evaluation and so evaluating (/ 100 0) raise division by zero error.
   
We use "if" construct as any other function by passing predicates and expressions as arguments to function. But in Scheme (or lisp) the "if" function is a specially made one since applicative order evaluation makes problems. This scenario will be more clear with the example: Square Roots by Newton's Method.

(define (absolute x)
    (cond ((< x 0) (- x))
        (else x)))
      
(define (good guess x)
    (< (absolute (- (* guess guess) x)) 0.001))


(define (improvguess guess x)
    (/ (+ guess (/ x guess)) 2))
  
(define (sqroot guess x)
    (if (good guess x)
        guess
        (sqroot (improvguess guess x) x)))

Function (sqroot guess x) is recursively called here. The termination of recursion occurs when function (good guess x) returns a boolean true value.
   
In the example let us replace "if" by a user defined function "new-if" which obeys applicative order evaluation, as follows.



(define (new-if x y z)
    (cond (x y)(else z)))

(define (sqroot guess x)
    (if (good guess x)
        guess
        (sqroot (improvguess guess x) x)))

define (p) (p))
       
Function (sqroot (improvguess guess x) x))) will be evaluated whenever the "new-if" function is called, yielding infinite recursive calls.
       
   





No comments:

Post a Comment