0

When I typed my original solution to subproblem b. of exercise 2.29 in SICP:

(define (total-weight m)
  (let ((left (left-branch m))
        (right (right-branch m)))
    (cond ((null? m) 0)
          ((not (pair? m)) m)
          (else
           (+ (total-weight (branch-structure left))
              (total-weight (branch-structure right)))))))

and tested it with the following data:

(define left1 (make-branch 5 8))
(define right1 (make-branch 7 10))
(define m1 (make-mobile left1 right1))
(define right2 (make-branch 1 3))
(define m2 (make-mobile left2 right2))
(define left0 (make-branch 12 m1))
(define right0 (make-branch 5 m2))
(define m0 (make-mobile left0 right0))
(total-weight m0)

The interpreter (MIT/GNU Scheme) reported error: "the object 3, passed as the first argument to cdr, is not the correct type". But when I eliminated the expression

(let ((left (left-branch m))
      (right (right-branch m)))
  ...)

with the following code:

(define (total-weight m)
  (cond ((null? m) 0)
        ((not (pair? m)) m)
        (else
         (+ (total-weight (branch-structure (left-branch m)))
            (total-weight (branch-structure (right-branch m)))))))

the program worked fine and printed the result

;Value: 27

I got confused. Can anybody take a trial on this problem and help me out?

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • the two versions are equivalent. – Will Ness May 30 '13 at 18:25
  • @Will Except that in the version using `let`, `m` is used before it is tested. – Terje D. May 30 '13 at 19:11
  • @TerjeD. i'll go eat my humble pie now. :) – Will Ness May 30 '13 at 19:13
  • don't forget to accept the answer which answers your question. :) Click on big green empty V-sign outline next to it. (you get +2 rep for that). – Will Ness May 31 '13 at 05:28
  • @WillNess Thank you for reminding! I've accepted Terje's answer. Besides, I'm new to here and very grateful to see so many zealous friends! :-) – Larry Amway May 31 '13 at 12:52
  • @LarryAmway no pressure; you can always take your time accepting - while there's no accept you're more likely to attract new answers. You can always un-accept later and accept another answer, which answers your question better. But if some answer *does* provide you a solution, then do accept it - to signal to others you're problem is solved, and to say thanks to the answerer. They will get +15 rep bump. :) – Will Ness May 31 '13 at 14:03

1 Answers1

4

The problem is that in the first version, (left-branch m) and (right-branch m) is called before you check whether or not m represents a mobile. i.e. m can be a number, or nil.

Terje D.
  • 6,250
  • 1
  • 22
  • 30
  • It does make sense! Without your help, it would be a long period for me to find out this deficiency of my understanding of 'let'. Thank you so much, warmed-hearted boy! :-) – Larry Amway May 31 '13 at 12:25