chrono

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 ...)とする。
    • そして,もっと良いのはlet式を使う
  • 関数内部での(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
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。
添付ファイル