sicp-ex-2.78



<< Previous exercise (2.77) | Index | Next exercise (2.79) >>


 ;; ----------------------------------------------- 
 ;; EXERCISE 2.78 
 ;; ----------------------------------------------- 
  
 (define (attach-tag type-tag contents) 
   (if (number? contents) 
       contents 
       (cons type-tag contents))) 
  
 (define (type-tag datum) 
   (cond ((number? datum) 'scheme-number) 
         ((pair? datum) (car datum)) 
         (else (error "Wrong datum -- TYPE-TAG" datum)))) 
  
 (define (contents datum) 
   (cond ((number? datum) datum) 
         ((pair? datum) (cdr datum)) 
         (else (error "Wrong datum -- CONTENTS" datum)))) 

Siki

The answer above doesn't follow the requirement in this exercise. The right answer should be:

  
 (define (type-tag datum) 
   (cond ((number? datum) datum) 
         ((pair? datum) (car datum)) 
         (else (error "Wrong datum -- TYPE-TAG" datum)))) 
  
 (define (contents datum) 
   (cond ((number? datum) datum) 
         ((pair? datum) (cadr datum)) 
         (else (error "Wrong datum -- CONTENGS" datum)))) 
  
 (define (attach-tag tag content) 
   (cond ((number? content) content) 
         ((pair? content) (cons tag content)))) 
  


The above correction is wrong. The original answer is correct.

The differences in and problems with the correction are as follows:

torinmr

Hmmm, I believe that the top version does have a bug, but it's not the one mentioned by Siki. The bug is that the condition in attach-tag should be

 (eq? type-tag 'scheme-number) 

Instead of

 (number? contents) 

This is because it's possible to create a tagged data type where the contents is just a number, but the type-tag is not scheme-number. (For example, suppose we implemented a "logarithm" type for storing very large numbers, where the stored value was the natural logarithm of the number we were representing.)


noname

If the above is correct, then the book itself is wrong, as it says explicitly to represent native numbers without the 'scheme-number symbol.


atomik

I agree with torinmr. Checking the type-tag argument passed to attach-tag eliminates any ambiguity about what type the user wants the contents of their datum to have. Native numbers can still be represented if the attach-tag function simply returns the contents parameter like so:

 (define (attach-tag type-tag contents) 
     (if (eq? type-tag 'scheme-number) 
         contents 
         (cons type-tag contents))) 

This does not violate the instructions given in the book which say "ordinary numbers should be represented simply as Scheme numbers rather than as pairs whose car is the symbol 'scheme-number"

Too elaborate on the example torinmr gave, if the user wants to run

 (attach-tag 'log 5) 

the version given in this comment will return '(log 5). The implementations given at the top of the page will return 5, thus breaking any operations which expect data tagged with the 'log symbol. If the user runs

 (attach-tag 'scheme-number 5) 

the version given in this comment will return 5, just like the implementations given at the top of the page.