SICP Practice

Practice 2.76

Explicit-despatch

(define (op1 z) 
  (cond ((eq? (get-tag z) tag1) (op1-type1 (content z)))
        ((eq? (get-tag z) tag2) (op1-type2 (content z)))
        (else
          (error "type error"))))

add new type type3

(define (op1 z)
  (cond ((eq? (get-tag z) tag1) (op1-type1 (content z)))
        ((eq? (get-tag z) tag2) (op1-type2 (content z)))
        ((eq? (get-tag z) tag3) (op1-type3 (content z)))
        (else
          (error "type error"))))

add new op opt2

(define (opt2 z)
  (cond ((eq? (get-tag z) tag1) (op2-type1 (content z)))
        ((eq? (get-tag z) tag2) (op2-type2 (content z)))
        (else
          (error "type error"))))

Data-Directed

type1type2
op1op1-type1op1-type2
op2op2-type1op2-type2
(define (op z)
  ((get 'op (tag z)) (content z)))

add new type type3

type1type2type3
op1op1-type1op1-type2op1-type3
op2op2-type1op2-type2op2-type3
(put 'op1 'type3 op1)
(put 'op2 'type3 op2)

add new op op3

type1type2
op1op1-type1op1-type2
op2op2-type1op2-type2
op3op3-type1op3-type2
(put 'op3 'type1 op3-type1)
(put 'op3 'type2 op3-type2)

Message passing

type1type2
op1op1-type1op1-type2
op2op2-type1op2-type2
(define (make-data-from-type1 x.y)
  (define (dispatch op)
    (cond ((eq? op 'op1) (op1-type1 x.y))
          ((eq? op 'op2) (op2-type1 x.y))
          (else 
            (error "type error"))))
  dispatch)

(define (make-data-from-type2 x.y)
  (define (dispatch op)
    (cond ((eq? op 'op1) (op1-type2 x.y))
          ((eq? op 'op2) (op2-type2 x.y))
          (else 
            (error "type error"))))
  diapatch)

add new type type3

(define (make-data-from-type3 x.y)
  (define (dispatch op)
    (cond ((eq? op 'op1) (op1-type3 x.y))
          ((eq? op 'op2) (op2-type3 x.y))
          (else 
            (error "type error"))))
  diapatch)

### add new op op3

(define (make-data-from-type1 x.y)
  (define (dispatch op)
    (cond ((eq? op 'op1) (op1-type1 x.y))
          ((eq? op 'op2) (op2-type1 x.y))
          ((eq? op 'op3) (op3-type1 x.y))
          (else 
            (error "type error"))))
  dispatch)

(define (make-data-from-type2 x.y)
  (define (dispatch op)
    (cond ((eq? op 'op1) (op1-type2 x.y))
          ((eq? op 'op2) (op2-type2 x.y))
          ((eq? op 'op3) (op3-type2 x.y))
          (else 
            (error "type error"))))
  diapatch)

if add new type use message passing and data-directed

if add new operator use explicit-dispatch and data-directed