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

  type1 type2
op1 op1-type1 op1-type2
op2 op2-type1 op2-type2
(define (op z)
  ((get 'op (tag z)) (content z)))

add new type type3

  type1 type2 type3
op1 op1-type1 op1-type2 op1-type3
op2 op2-type1 op2-type2 op2-type3
(put 'op1 'type3 op1)
(put 'op2 'type3 op2)

add new op op3

| | type1 | type2 | | —-| :—: |:—-: | | op1 | op1-type1 | op1-type2 | | op2 | op2-type1 | op2-type2 | | op3 | op3-type1 | op3-type2 |

(put 'op3 'type1 op3-type1)
(put 'op3 'type2 op3-type2)

Message passing

  type1 type2
op1 op1-type1 op1-type2
op2 op2-type1 op2-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