Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Racket Lisp : comparison between new-if and if

(define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter(improve guess x)
                  x)))

(define (improve guess x)
  (average guess(/ x guess)))

(define (average x y)
  (/ (+ x y) 2))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.0001))

(define (square x)
  (* x x))

(define (sqrt-g x)
  (sqrt-iter 1.0 x))

This is a program for sqrt. And the question is what happens when you attempts to use new-if to replace if with new-if.

(define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter(improve guess x)
                  x)))

This is new if

 (define (new-if predicate then-clause else-clause)
      (cond (predicate then-clause)
            (else else-clause)))

My opinion is the result of two program gonna be the same. because new-if and if can produce the same results.

However, new-if proved wrong, because it is a dead circle when I tried.

So, why?

like image 230
Jerry Zhao Avatar asked Dec 15 '22 19:12

Jerry Zhao


2 Answers

new-if is a function. All the arguments to a function are evaluated before calling the function. But sqrt-iter is a recursive function, and you need to avoid making the recursive call when the argument is already good enough.

The built-in if is syntax, and only evaluates the then-branch or else-branch, depending on the value of the condition.

You can use a macro to write new-if.

like image 198
Barmar Avatar answered Jan 08 '23 09:01

Barmar


This is the perfect example for demonstration the algebraic stepper! In the the algebraic stepper you can see how the course of the computation differs from your expectation. Here you must pay notice to the differences in evaluation of, say, (new-if 1 2 3) and (if 1 2 3).

If you haven't tried the algebraic stepper before, see this answer to see what it looks like.

like image 39
soegaard Avatar answered Jan 08 '23 09:01

soegaard