exercise 3.35

雛形はできてるし、adderとかの例もあるので簡単かな。

(define (square n) (* n n))

(define (squarer a b)
  (define (process-new-value)
    (if (has-value? b)
        (if (< (get-value b) 0)
            (error "square less than 0 -- SQUARE" (get-value b))
            (set-value! a
                        (sqrt (get-value b))
                        me)))
    (if (has-value? a)
        (set-value! b
                    (square (get-value a))
                    me)))
  (define (process-forget-value)
    (forget-value! a me)
    (forget-value! b me)
    (process-new-value))
  (define (me request)
    (cond ((eq? request 'I-have-a-value)
           (process-new-value))
          ((eq? request 'I-lost-my-value)
           (process-forget-value))
          (else
           (error "Unknown request -- SQUARER" request))))
  (connect a me)
  (connect b me)
  me)

実行結果は

gosh> (define a (make-connector))          
a                                          
gosh> (define b (make-connector))          
b                                          
gosh> (probe 'a a)                         
#<closure (probe me)>                      
gosh> (probe 'b b)                         
#<closure (probe me)>                      
gosh> (squarer a b)                        
#<closure (squarer me)>                    
gosh> (set-value! b 100 'k0ncha)           
                                           
Probe: a = 10.0                            
                                           
Probe: b = 100                             
done                                       
gosh> (forget-value! b 'k0ncha)            
                                           
Probe: a = ?                               
                                           
Probe: b = ?                               
done                                       
gosh> (set-value! a 5 'k0ncha)             
                                           
Probe: b = 25                              
                                           
Probe: a = 5                               
done