SICPゼミ第22回

練習問題3.32

入力を 0,1 → 1,1 → 1,0 と変化させたとき振る舞いが変わる。
一回目の入力の変化で「出力を1にする」という予定が追加され、その後2回目の入力の変化で「出力を0にする」という予定が追加される。キューだとこの順番に処理されるので出力は最終的に0だが、リスト(要するにスタック)を使うと逆に処理されるので最終出力が1になりおかしい。

by dolicas

練習問題3.33
(define (averager a1 a2 ave)
  (define (process-new-value)
    (cond ((and (has-value? a1) (has-value? a2))
           (set-value! ave
                       (/ (+ (get-value a1) (get-value a2)) 2)
                       me))
          ((and (has-value? a1) (has-value? ave))
           (set-value! a2
                       (- (* 2 (get-value ave)) (get-value a1))
                       me))
          ((and (has-value? a2) (has-value? ave))
           (set-value! a1
                       (- (* 2 (get-value ave)) (get-value a2))
                       me))))
  (define (process-forget-value)
    (forget-value! ave me)
    (forget-value! a1 me)
    (forget-value! a2 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: ADDER" request ))))
  (connect a1 me)
  (connect a2 me)
  (connect ave me)
  me)

実行結果

> (define A (make-connector))
> (define B (make-connector))
> (define C (make-connector))
> (averager A B C)
#<procedure:me>
> (probe "A" A)
#<procedure:me>
> (probe "B" B)
#<procedure:me>
> (probe "C" C)
#<procedure:me>
> (set-value! A 20 'user)

Probe: A = 20'done
> (set-value! B 50 'user)

Probe: B = 50
Probe: C = 35'done

動いた。かわいい。

by tube

組み合わせて作れという制約を守ったのがこちら

(define sophie (make-connector))
(define rorona (make-connector))
(define meruru (make-connector))
(define (averager sophie rorona meruru)
  (let ((ayesha (make-connector))
        (escha (make-connector)))
    (adder sophie rorona escha)
    (multiplier meruru ayesha escha)
    (constant 2 ayesha)
    'ok))

実行結果

> (averager sophie rorona meruru)
'ok
> (has-value? sophie)
#f
> (set-value! sophie 5 'user)
'done
> (set-value! rorona 7 'user)
'done
> (probe "sophie" sophie)

Probe: sophie = 5#<procedure>
> (probe "rorona" rorona)

Probe: rorona = 7#<procedure>
> (probe "meruru" meruru)

Probe: meruru = 6#<procedure>
> 

幼女コネクタかわいい by ふえはうたう

練習問題3.35
(define (squarer a b)
  (define (process-new-value)
    (if (has-value? b)
        (if (< (get-value b) 0)
            (error "square less than 0: SQUARER"
                   (get-value b))
            (set-value! a (sqrt (get-value b)) me))
        (if (has-value? a)
            (set-value! b (* (get-value a) (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)

by pine

練習問題3.36

f:id:sicp-zemi:20160824174140j:plain

練習問題3.37
(define (c+ x y)
	(let ((z (make-connector )))
		(adder x y z)
		z))

(define (c- x y)
	(let ((z (make-connector)))
		(adder y z x)
		z
		)
	)

(define (c* x y)
	(let ((z (make-connector)))
		(multiplier x y z)
		z
		)
	)

(define (c/ x y)
	(if (eq? y 0)
		(error "division by zero")
		(let ((z (make-connector)))
			(multiplier y z x)
			z
			)
		)
	)

(define (cv value)
	(let ((z (make-connector)))
		(constant value z)
		z
		)
	)

by dolicas