勉強ノート - SICP(1)
さて、方法序説だけ読んでても意味がないので、「計算機プログラムの構造と解釈」も読み始めましたよー。
いやー、Amazonの書評で「翻訳がウンコだ」みたいな事が書いてありますが、全然普通に読めるじゃないですか。ドスエフスキーやカーの翻訳モノに比べれば遙かに読みやすいッス。
- 作者: ジョン・ディクスン・カー,三田村裕
- 出版社/メーカー: 早川書房
- 発売日: 1979/07
- メディア: 文庫
- クリック: 13回
- この商品を含むブログ (57件) を見る
重要かなと思ったキーワード
- 正規順序、作用的順序
- 基本式、組み合わせ法、抽象化法
勉強にはUbuntu+Gaucheでやってます。VPCの中です。これわざわざ(display …)とかやらないと色々出てこないのかなー?超面倒なんだけど。色々調べてみよう。
問題と考察
※青字はコメントです。
問題1.1
それぞれの式で解釈系が印字する結果は何か。
10 ;; 10 (+ 5 3 4) ;; 12 (- 9 1) ;; 8 (/ 6 2) ;; 3 (+(* 2 4)(- 4 6)) ;; 6 (define a 3) ;; a (中身は3) (define b (+ a 1)) ;; b (中身はa+1=4) (+ a b (* a b)) ;; 3 + 4 + (12) = 19 (= a b) ;; aにbを代入するのかと思った・・・。 ;; (a == b)で#f(=false)になるだけ。 (if(and(> b a) (< b (* a b)) ) b a) ;; (b > a && b < a * b) == trueなのでbがでる。4 (cond((= a 4) 6) ((= b 4) (+ 6 7 a)) (else 25)) ;; a==4がfalseでb==4がtrueなので6+7+a -> 16 (+ 2 (if(> b a) b a)) ;; 6 (* (cond((> a b) a) ((< a b) b) (else - 1)) (+ a 1)) ;; b * (a + 1) -> 16
問題1.2
次の式を前置記法に翻訳せよ。
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7)))
問題1.3
三つの数を引数として取り、大きい二つの数の二乗の和を返す手続きを定義せよ。
これは考えている間に、相当カオスになった・・・。普通にCとかで書いてもダメになりそう(汗。へたれですから。
(define (f x y z)( if (> x y) (if(> y z) (+ (* x x) (* y y)) (+ (* x x) (* z z))) (if(> x z) (+ (* x x) (* y y)) (+ (* y y) (* z z))) ) )
間違ってないけどスマートじゃない気がする。ググるとだいたいみんなこの方法に似たり寄ったり。(よくわからんから直球で・・・みたいな)
海外の情報をググったところ、いろんな方法が見つかったよ!
(define (sum-of-two-larger a b c) (if (> a b) (+ a (if (> b c) b c)) (+ b (if (> a c) a c))))
↑Drink! Girls! Feck! Arse!
直球型より少し賢い。
(define (ex3 x y z) (+ (square (max x y)) (square (max (min x y) z))))
↑4chan
なんだよsquareって。なんだよmax、minて(涙。
4chanでも「SICP doesn't even mention min and max at that point.」(本的にmaxやminはまだ言及されてないぞ)ってツッコミが入ってます。
(define (ex3 x y z) (- (+ (square x) (square y) (square z)) (square (min x y z))))
↑同じく4chan
この発想はなかった。しかし、この問題はセンス丸見えですな。
問題 1.4
次の手続きの振る舞いは?
(define (a-plus-abs-b a b) ((if (> b 0) + -) a b))
なんでもありかよ・・・。恐るべしScheme。
bが正なら加算。負だと減算になるんだけど負の値を減算する事になる。結果 a+|b| をしてる。
問題 1.5
次の手続きは作用的順序の場合と正規順序の場合、それぞれどうなる?
(define (p) (p)) (define (test x y) (if (= x 0) 0 y)) (test 0 (p))
pがおかしなな事に!!
これって展開できるのか?(p)とかやったら即死しそうなんだけど。
実験してみよう。・・・やっぱり止まった。無限ループしてるっぽく感じる。
つまり
(if (= 0 0) 0 (p))
こう展開されていないって事だよね。つーことはGaucheは作用的順序で展開したって事ですね。
答えとしては
- 正規順序の場合:(if (= 0 0) 0 (p))で0が返る
- 作用的順序の場合:(test 0 (p))で(p)を展開しようとして死ぬ
テンションあがる!
問題1.3の別の解を探しているときが一番楽しかった!この調子でどんどん勉強するぞっ
最初はカッコだらけでどうなるかと思ったけど、自分でやってみたらどうという事はなかったなー。