David J.
David J.

Reputation: 1913

what's wrong with this basic scheme function

I'm trying to write a scheme function that does the following (taken from SICP):

Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.

Here's my attempt:

(define (square-sum-larger a b c)
  (cond ((and (< a b) (< a c))) (+ (* b b) (* c c)))
  (cond ((and (< b c) (< b a))) (+ (* a a) (* c c)))
  (cond ((and (< c a) (< c b))) (+ (* b b) (* a a)))
)

When I enter this into the biwa scheme interpreter, I get the following:

(square-sum-larger 4 5 6)
16

Since 4 is less than 5 and 6, shouldn't the first condition be evaluated, meaning that the sum of the squares of 5 and 6 should be returned?

Upvotes: 0

Views: 83

Answers (2)

Sylwester
Sylwester

Reputation: 48745

(define (square-sum-larger a b c)
  (cond ((and (< a b) (< a c))) (+ (* b b) (* c c)))
  (cond ((and (< b c) (< b a))) (+ (* a a) (* c c)))
  (cond ((and (< c a) (< c b))) (+ (* b b) (* a a)))
)

Is basically this in JS:

function squareSumLarge(a, b, c) {
   // not tail position , dead code regardless if the test is truthy
   if (a < b && a < c) {
     b * b + c * c;
   }
   // not tail position , dead code regardless if the test is truthy
   if (b < c && b < a) {
     a * a + c * c;
   }
   if (c < a && c < b0 {
     // return because cond is in tail position 
     return b * b + a * a; 
   } else {
     // if the last cond term didn't hit it returns an implementation chosen value
     return undefined;        
   } 
}

Know that this pattern:

if (test1) {
  return expression1;
} elseif (test2) {
  return expression2;
} else {
  return expression3;
}

is done like this with cond when the cond is in tail position:

(cond 
  (test1 expression1)
  (test2 expression2)
  (else expression3))

Upvotes: 1

Kaz
Kaz

Reputation: 58510

(define (square-sum-larger a b c)
  (cond ((and (< a b) (< a c))) (+ (* b b) (* c c))) ;; this is thrown away
  (cond ((and (< b c) (< b a))) (+ (* a a) (* c c))) ;; this is thrown away
  (cond ((and (< c a) (< c b))) (+ (* b b) (* a a)))
)

Only the last of the three cond does anything useful; the previous cond expressions do not have any side effect, since they perform only calculations, and their value is not used. The are dead code which a Scheme compiler can eliminate entirely.

You probably wanted to combine all of the clauses into a single cond:

(define (square-sum-larger a b c)
  (cond ((and (< a b) (< a c))) (+ (* b b) (* c c))
        ((and (< b c) (< b a))) (+ (* a a) (* c c))
        ((and (< c a) (< c b))) (+ (* b b) (* a a))))

Upvotes: 2

Related Questions