SICP 読み (31) 2.2.4 例: 図形言語
stub の実装を検討するのが面倒なので試験ドリブンは略。
図 2.9 の手続きも紹介されている。
(defiine (square-limit painter n) (let ((quater (corner-split painter n))) (let ((half (beside (flip-horiz quater) quater))) (below (flip-vert half) half))))
ざっくりベースな処理として、元画像と元画像を左右反転させたナニと、そのナニを上下反転させたソレを below する、と。実装は置いとくとして、意味が分かりやすい、というのも抽象表現のおかげか。
動作するかどうかは置いといて、問題 2.44 の解と思われる手続きを以下に。
(define (up-split painter n) (if (= n 0) painter (let ((smaller (up-split painter (- n 1)))) (below painter (beside smaller smaller)))))
とりあえず、実装に拘らずに検討した方が良さげな感じがする。
高階演算
パターンの抽象化ですか。括弧で括る、という作業に似てはいるが、マトメた結果できるのが手続きってあたりが算数と違うのか。小学校あたりでこんなソレを教えてくれてたら、もう少し日本とゆー国も違ってくるんじゃね??という微妙なナニはさて置き。
問題 2.45 は上記な作業を要求しているな。動作確認できんので、間違えてるかもしれん、というのを前提に以下。
(define (split p1 p2) (lambda (painter n) (let f ((painter painter) (n n)) (if (= n 0) painter (let ((smaller (f painter (- n 1)))) (p1 painter (p2 smaller smaller)))))))
フレーム
うーん。スルーしすぎなのかなぁ。なんか落ちてない感満載。あ、原点が mapping できればあとはベクタだから良いのか??
とりあえず以下に問題 2.46 の解を。
(define (make-vect x y) (list x y)) (define (xcor-vect v) (car v)) (define (ycor-vect v) (cadr v)) (define (add-vect v1 v2) (make-vect (+ (xcor-vect v1) (xcor-vect v2)) (+ (ycor-vect v1) (ycor-vect v2)))) (define (sub-vect v1 v2) (make-vect (- (xcor-vect v1) (xcor-vect v2)) (- (ycor-vect v1) (ycor-vect v2)))) (define (scale-vect s v) (make-vect (* s (xcor-vect v)) (* s (ycor-vect v))))
問題 2.47 も以下に。このパターンは試験ドリブンにしておくと確認が楽だな。てーか楽ちんすぎて本当に良いのかどうか不安になるな。
まず一つめ。
(define (make-frame origin edge1 edge2) (list origin edge1 edge2))
選択子 (selector) は以下。
(define (origin-frame f) (car f)) (define (edge1-frame f) (cadr f)) (define (edge2-frame f) (caddr f))
次は以下。
(define (make-frame origin edge1 edge2) (cons origin (cons edge1 edge2)))
選択子 (selector) は以下。
(define (origin-frame f) (car f)) (define (edge1-frame f) (cadr f)) (define (edge2-frame f) (cddr f))
次の節あたりから具体的になってくるか。