3.31 Exercise 3.31
This is the interactive session that we are expecting to see, with accept-action-procedure immediately running the procedure after adding it ot the list:
> (define input-1 (make-wire)) > (define input-2 (make-wire)) > (define sum (make-wire)) > (define carry (make-wire)) > (probe 'sum sum)
sum 0 New value = 0
> (probe 'carry carry)
carry 0 New value = 0
> (half-adder input-1 input-2 sum carry) 'ok
> (set-signal! input-1 1) 'done
> (propagate)
sum 8 New value = 1
'done
> (set-signal! input-2 1) 'done
> (propagate)
carry 11 New value = 1
sum 16 New value = 0
'done
If we change the definition to not do this, we get this session:
(define (make-wire-bad) (let ((signal-value 0) (action-procedures '())) (define (set-my-signal! new-value) (if (not (= signal-value new-value)) (begin (set! signal-value new-value) (call-each action-procedures)) 'done)) (define (accept-action-procedure! proc) (set! action-procedures (cons proc action-procedures))) (define (dispatch m) (cond ((eq? m 'get-signal) signal-value) ((eq? m 'set-signal!) set-my-signal!) ((eq? m 'add-action!) accept-action-procedure!) (else (error "Unknown operation -- WIRE" m)))) dispatch))
> (define the-agenda (make-agenda)) > (define input-1 (make-wire-bad)) > (define input-2 (make-wire-bad)) > (define sum (make-wire-bad)) > (define carry (make-wire-bad)) > (probe 'sum sum) > (probe 'carry carry) > (half-adder input-1 input-2 sum carry) 'ok
> (set-signal! input-1 1) 'done
> (propagate) 'done
> (set-signal! input-2 1) 'done
> (propagate)
carry 11 New value = 1
'done
Because action procedures are not run after being added to wires, the initial values of the wires are not propagated, meaning that later calculations are not done corrrectly.