Schemeで身長と体重を記録するプログラムを書いてみた
今日は、Schemeの変数周辺を試してみる。自分用の備忘録。
SICPの3.1節のdispatchを参考にして実験しているのだが、Schemeの(局所)変数は、Cの変数よりもむしろC++のクラスに近い気がする。
(ものすごくざっくりした言い方だが)かっこで囲んだ部分がどんどん内部環境になっていくScheme。内部に登録した局所変数の値を取り出すだけでも、手続きを用意しなければいけない。
次のheight-weight-dataは、SICPの3.1節のmake-accountをまねして、さらに単純化した例である。これは身長と体重を記録するためのプログラムだ。
(define (height-weight-data name height weight) (define (dispatch m) (cond ((eq? m 'name) name) ((eq? m 'height) height) ((eq? m 'weight) weight))) dispatch)
a1にtaro、a2にjiroのデータを入力してみる。
(define a1 (height-weight-data 'taro 170 70))
=>a1
(define a2 (height-weight-data 'jiro 190 100))
=>a2
このようにa1,a2を定義すると、a1とa2は、データ構造は同じであるが、全く別のデータを持つ。
(a1 'name)
=>taro
(a1 'height)
=>170
(a1 'weight)
=>70
(a2 'name)
=>jiro
(a2 'height)
=>190
(a2 'weight)
=>100
(> (a1 'height) (a2 'height))
=>#f
身長、体重を更新できるようにしたのが、以下のheight-weight-dataだ。
(define (height-weight-data name height weight) (define (renew-height new-height) (set! height new-height) height) (define (renew-weight new-weight) (set! weight new-weight) weight) (define (dispatch m) (cond ((eq? m 'name) name) ((eq? m 'height) height) ((eq? m 'weight) weight) ((eq? m 'renew-height) renew-height) ((eq? m 'renew-weight) renew-weight))) dispatch)
(define a1 (height-weight-data 'taro 170 70))
=>a1
(define a2 (height-weight-data 'jiro 190 100))
=>a2
((a1 'renew-height) 172)
=>172
((a1 'renew-weight) 73)
=>73
(a1 'height)
=>172
(a1 'weight)
=>73
(a2 'height)
=>190
(a2 'weight)
=>100
この例では、プログラマの意図通り、taroとjiroの身長、体重を別々に扱えている。SICPの受け売りではあるが、こういった感じで、Schemeはデータをかなり直感的にわかりやすい形で、記録、更新できる。