chronoのページ
買うだけ買って,前書きしか読んでいませんでした。
この機会に読破を目指します。
既に目標から遅れていますが,マイペースで読み進めようと思っています。
環 境
SCIP: 日本語訳のみ
解釈系: gauche 0.8.12 [utf-8,pthreads]
エディタ: Emacs 22.1.1
OS: Debian lenny
はまり中
なし
メモ
let, let*, letrec
let, let*, letrecの違いは束縛された変数のスコープの違い。
(let/let*/letrec <束縛部> <本体>)に対して,
- let: 束縛した変数は本体のみをスコープとする
- let*: 束縛した変数は,束縛した直後から本体までをスコープとする
- letrec: 束縛した変数は,束縛部の最初から本体までをスコープとする
letrecのスコープにより,letrecは変数の束縛時には,参照できる(束縛に
使える)変数が定まっていない。
そのため,letrecの束縛時には,変数など"不定な"ものは使用できない
(関数は実行時に評価されるので,束縛時は不定ではない)。
(と予想)
はまった問題
1.29
はまった回答
; シンプソンの公式
(define (simpson f a b n)
(define (simpson-h)
(/ (ー b a) n))
(define (simpson-sum k)
(define (simpson-y)
(f (+ a (* k (simpson-h)))))
(cond (= k 0) (simpson-y)
(= k n) (simpson-y)
(even? k) (* 2 (simpson-y))
(else (* 4 (simpson-y)))))
; 本体
(* (/ (simpson-h) 3)
(sum simpson-sum 0 inc n)))
(simpson cube 0 1 100)の結果が0になる。
何が問題か (Thanks to Alyssaさん, kacchiさん)
cond式の書き方を間違えていた。
そのため,(= k 0)は条件式ではなく(if = (begin k 0))と評価された。
ここで,Schemeでは全ての値は真偽値を持ち,明確に#fと定義されていないものは
全て#tとして扱われるため,(if = ...は真となり,(begin k 0)が評価される。
そして(begin k 0)は0を返すので,(cond ...)の式は常に0を返していた。
その結果,(simpson cube 0 1 100)の結果が0になった。
その他の知見
- (define (hoge) ...) は引数無しの関数を定義している。定数を定義するなら,(define hoge ...)とする。
- 関数内部での(define ...)は,色々と良くないことがある(らしい==後々分かるとのこと)
練習問題回答
2.29
なんとなく頑張って作ったから
(define (make-mobile left right)
(list left right))
(define (make-branch length structure)
(list length structure))
;;; (a)
(define (left-branch mobile)
(car mobile))
(define (right-branch mobile)
(car (cdr mobile)))
(define (branch-length branch)
(car branch))
(define (branch-structure branch)
(car (cdr branch)))
;;; (b)
(define (total-weight mobile)
; (display "total-weight: ")(display mobile)(newline)
(cond ((null? mobile) 0)
((pair? mobile) ; 錘ではなくモービル
(+ (total-weight (branch-structure (left-branch mobile)))
(total-weight (branch-structure (right-branch mobile)))))
(else mobile))) ; 錘
;;; (c)
(define (balanced-mobile? mobile)
(define (moment branch)
(* (branch-length branch) (total-weight (branch-structure branch))))
; (display "balanced-mobile?: ")(display mobile)(newline)
(if (not (pair? mobile)) #t ; 錘のときは無条件で真
; 以下,mobile が モービルの時
(let* ((left (left-branch mobile))
(right (right-branch mobile))
(left-moment (moment left))
(right-moment (moment right)))
(if (= left-moment right-moment)
(and ; 左右ともにbalanced?
(balanced-mobile? (branch-structure left))
(balanced-mobile? (branch-structure right)))
#f)))) ; 左右のバランスが等しくない
;;; (d)
; 変更不要??? ← まちがい 上の定義を書き換えたらtestが通らない
; 要素が2個のリストだから
;;; ------------------------- test ---------------------------
(define (mobile-test mobile)
(display "-----mobile test-----")(newline)
(display "mobile-test(display): ")(display mobile)(newline)
(display "mobile-test(total): ")(display (total-weight mobile))(newline)
(display "mobile-test(balanced): ")(display (balanced-mobile? mobile))(newline))
(define m0 2)
(mobile-test m0)
(define m1 (make-mobile (make-branch 1 2) (make-branch 3 4)))
(mobile-test m1)
(define m2 (make-mobile (make-branch 5 6) (make-branch 7 m1)))
(mobile-test m2)
;;; ちゃんとしたモービル
(define m3-1 (make-mobile (make-branch 1 1) (make-branch 1 1)))
(define m3-2 (make-mobile (make-branch 1 2) (make-branch 2 1)))
(define m3-3 (make-mobile (make-branch 1 m3-2) (make-branch 1 3)))
(define m3-4 (make-mobile (make-branch 3 2) (make-branch 1 m3-3)))
(define m3 (make-mobile (make-branch 8 m3-1) (make-branch 2 m3-4)))
(mobile-test m3)
最終更新:2008年01月31日 01:36