SICP
「3.5.2 無限ストリーム」に入りました。こういう風にリストを定義すると、永遠に続く配列を表現できるということが驚きでした。このトピックは問題がたくさんあるので、それらを解きながら、理解を深めていきたいと思います。 問題3-53。stream-carの値を足し…
問題3-56。2の倍数のストリーム、3の倍数のストリーム、5の倍数のストリームをマージして、一つのストリームに作成するためには、以下のような手続きを定義します。 (define S (cons-stream 1 (merge (scale-stream integers 2) (merge (scale-stream intege…
「3.5 ストリーム」の節に入り、「遅延評価」という概念が登場してきました。「遅延評価」という言葉そのものは、様々なブログで紹介されていて興味を持っていましたが、それが一体何なのかということは全く知りませんでした。まだ冒頭の数ページしか読んでいませ…
昨日の続きで、共有資源を複数のプロセスがアクセス・変更する際に発生する問題点について考察していきます。 問題3-43。二つの口座の残高差分を交換するexchangeですが、exchange手続き全体を直列化しないと、以下のような問題が発生する可能性があります。…
この部分では、mutexが登場し、make-sirializerの実装が紹介されています。さらに、デッドロックについても言及されています。 問題3-46。mutexが保持しているフラグを調べ、利用可能ならばフラグを上げる手続きであるtest-and-set!ですが、この中には、「フ…
「3.3.5 制約の拡散」の節は、ディジタル回路のような「遅延」は絡んでいないものの、未定義コネクタに値をセットした後、その値が制約に従って伝播していく様子などに見られる、コネクタや制約の仕組みが面白いと感じました。 問題3-33は、averagerを定義する問…
「3.4 並列性:時が本質的」に入りました。この節で述べられているようなことをしっかりと理解しておかないと、再現困難なバグを生み出してしまうので、本書だけでなく、様々な文献に当たりながら知見を深め、それを日常のプログラミングに反映させていきたい…
ここ最近、体調を崩していたため、勉強日記の更新が滞ってしまいましたが、少しずつリカバリーしていきたいと思います。 「3.3.4 ディジタル回路のシミュレータ」の節は、読み物として非常に面白く、問題量としては多くないものの、サンプルコードを読み解くの…
「3.3.3 表の表現」ということで、set-car!/set-cdr!を内部的に使いながら、テーブルの要素を追加・更新・削除できるようなデータ構造を構築していきます。 問題3-24では、「キーに該当する要素」を見つけるときに、equal?で厳密にチェックするのではなく、何ら…
キューに関する問題です。先頭・最後尾の対や前後の対を指し示すポインタを操作する練習でもあります。 問題3-21では、例文に掲載されている手続きで作成したキューを、視覚的にわかりやすく印字するためのメソッドを定義します。front-queueをそのまま使っ…
「3.2 評価の環境モデル」の節では、手続きがどのように評価されていくのかということについての新しい見方が提示されています。2〜3日かけて何度もじっくり読んでみました。置換えモデルは、カッコの中身を展開していって、元の手続きへ収束していくようなイ…
「3.3 可変データでのモデル化」の節に入りました。 問題3-12で、append!の動きを確認します。 (define (append! x y) (set-cdr! (last-pair x) y) x) (define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x)))) (define x (list 'a 'b)) (define y …
対が指す場所が等しいのか、データを指している対は同一なのか否か、ということに対する考察を深めていく部分です。 問題3-15は、set-to-wow!の効果を説明せよとのことです。 (define (set-to-wow! x) (set-car! (car x) 'wow) x) (define x (list 'a 'b)) (…
「3.1.3 代入を取り入れた代価」では、関数型プログラミングと命令型プログラミングの違いや、「同一」「変化」など重要なキーワードについて語られていて、非常に示唆に富んだ節だと感じました。本書の後続の部分で何かにつまずいたら、ここに戻ってこようとも思…
「3.1.2 代入を取り入れた利点」ということで、代入や局所変数という概念を使うことによる利点が述べられています。例えば、ランダムな値を引き出す手続きとして、(random x)のように何らかの引数を指定するのか、(rand)のようにrand手続きの中の局所変数を繰…
第三章に入りました。最初は代入に関する練習問題です。 問題3-1のアキュムレータ手続きです。 (define (make-accumulator init) (let ((sum init)) (lambda (x) (begin (set! sum (+ sum x)) sum)))) (define A (make-accumulator 5)) (A 10) ;=>15 (A 10) …
問題2-92以降については、問題文は読んでみたものの、コードを書いたとしてもそれが正しいかを検証するための数学的な知識が自分には足りていないと思ったので、今回は解くのをあきらめました。これでひとまず第二章は終了です。 かなり前から使っていたよう…
「2.5.3 例:記号代数」に入りました。多項式の算術演算を扱えるパッケージを定義します。polynominal型の構成要素は、一つの不定元と、各次数に関連づけられている係数の組み合わせのリストです。 本書に書いてあるパッケージ手続きを愚直に書いた上で、問題2…
一元多項式の除算を定義します。問題文を読みながら、商と剰余を求めるための数式を紙に書いて、何となく流れはわかりました。しかし、それを実装する段階で、商と剰余のリストをどのように返していいのかわからず、ウェブで模範解答を探したところ、ここに…
「整数->有理数->実数->複素数」というように、各型を拡大解釈するための順序が存在する場合、型のレベルを一段上げるための手続きraiseを定義してやれば、強制型変換ロジックを汎用化することができます。この中で、「実数」に関しては、これまで扱ってこなかっ…
raiseを使ってapply-genericを改善します。これによって、get-coercion/put-coercionやt1->t2のような型変換のベタ書きを排除することができます。まずは、オブジェクトツリーの各要素に自身のレベルを表す値を返すような手続きを追加しました。 ;(define (t…
型を単純化するdrop手続きを定義します。この問題に関しては、結構手間取った割には、まだまだ完全な解答を導きだせておらず、またこれまでのequ?やraiseの実装方法に重大な誤りがあったことを発見しました。 まずは、dropのインターフェイスを定義します。 …
複数の異なるデータ型を演算できるように機能追加していきます。まずは、Louis Reasonerの仮説が正しいかどうかを確認していきます。 (define (scheme-number->scheme-number n) n) (define (complex->complex z) z) (put-coercion 'scheme-number 'scheme-n…
昨日の続きです。まずは問題2-78。汎用演算のサンプルコードのままだと、単純な整数の数値を一つ作るためには、(make-scheme-number 3)みたいなことをやってscheme-numberのタグをつけなければなりません。この面倒臭さを解消するための問題です。タグつけの…
「2-5 汎用演算のシステム」の節に入りました。ここから先の問題に取り組むためには、本書に掲載されているコードを書かなければならず、それに結構時間がかかってしまいました。しかし、書いてみることで、今までの自分の理解不足を補えたという利点もありま…
put-get-genと問題2-74は時間をしっかりと作ってから取り組んでみようと思ってますので、次のメッセージパッシングの問題に進みます。 演算や型の定義をputを使って登録しつつ、getを用いて適用していくというやりかたではなく、型ごとに、その型で使われる…
いよいよ「2.4 抽象データの多重表現」の節に入りました。いかにソフトウェアを設計/実装すべきかということに対する多くのヒントを得られそうな予感がしています。 早速、問題2-73の記号微分を行なうプログラムの改修に取り組みました。しかし、putやgetは自…
Huffman符号化木に関する問題を解いています。可変長の符号をどのように定義して、decode/encodeをどのような処理で表現するのか、という点に面白味を感じました。以下は、本書に掲載されていた、Huffman木を作成する手続きと、decodeの手続きです。 (define…
まずは、Huffman符号化木を生成するための手続きを書きます。以下は、本書に掲載されていた例文で、記号とその重み付けの組み合わせリストから、Huffman-treeの葉の要素の並びを生成するロジックです。 (define (adjoin-set x set) (cond ((null? set) (list…
Huffman-treeを構成している記号が任意の数の場合、そこから生成される符号の大きさにどのような分布が見られるかを調べます。(問題2-71) (define 5-symbols '((a 1) (b 2) (c 4) (d 8) (e 16))) (encode '(a) (generate-huffman-tree 5-symbols)) ;=>(0 0 0…