(sicp29)試しに先の方のことを読んでみた。
問題を解く気力あなかったので、先の方を読んでみました。
その時に、メッセージパッシングが理解できた気がしたので、
実際に、作ってみました。
その後、読んだだけの状態を記憶しておける関数も
作れる気がしたので作ってみることにしました。
そしたら、できてしまいました。
(たぶん、後で読むと何か勘違いしているのかもしれません><)
;;メッセージパッシングはたぶん理解した。 ;;本当に理解したか確かめてみる。 ;;四則演算する関数をメッセージパッシングでつくれたら、 ;;本当に理解しているということにしておこう (define (calc op x y) (define (add x y) (+ x y)) (define (mul x y) (- x y)) (define dispatch (let ((p? (lambda (x) (eq? op x)))) (cond ((p? '+) (add x y)) ((p? '-) (mul x y)) (else (error "notfound" op))))) dispatch) ;;面倒なので"+", "-"だけでいいや (calc '+ 1 2) ;;1:user> => 3 ;;できてるできてる ;;さらに状態を持ったcalcをつくろう. ;;その前に,accumulatorをつくろう. (define (accumulator n) (let ((count n)) (lambda (x) (set! count (+ count x))))) (define acc (accumulator 30)) (acc 20) ;; 2:user> => acc ;; 3:user> => 50 ;; 4:user> => 70 ;; 5:user> => 90 ;; 6:user> => 110 ;; 7:user> => 130 ;; 8:user> => 150 ;;できた! ;;(50から先は、(acc 20)にカーソルを合わせてC-x eで評価を繰り返している) ;;accumulatorができたので、今度はcalc2 (define (calc2 init) (define (dispatch op) (let ((p? (lambda (it) (eq? op it)))) (cond ((p? '+ ) add) ((p? '- ) mul) (else (lambda (state x) state))))) (define (add m n) (+ m n)) (define (mul m n) (- m n)) (let ((state init)) (lambda (op x) (set! state ((dispatch op) state x))))) (define x (calc2 10)) (x '+ 10) (x '+ 20) (x '- 30) (x '* 30) ;; 9:user> => x ;; 10:user> => 20 ;; 11:user> => 40 ;; 12:user> => 10 ;; 13:user> => 10 ;;"*"は定義されてないので、現在の値が帰ってくる