今やっている部分がちょっと時間をかけすぎて全体像がボヤッとしてきてしまったのでページを戻りながら復習していきます。
2.4 抽象データの多重表現
データ抽象を用いることでデータの表現、演算、有理数を扱うプログラムといったレイヤ毎に分離し、複雑さを制御することができる。
ただし、この方法は十分ではない。
・同じものを別の形式を用いて表す
・異なる設計選択のものを共存できるようにする
・部品を加法的に用いて大きいシステムを組み立てる
ようなことを実現するための手法が必要。
→汎用手続きを構成する
・データをどう処理すればいいのか判断可能な、型タグを持つデータオブジェクトを用意する
・データ主導プログラミング
2.4.1 複素数の表現
複素数は複数の方法であらわすことができる
・直交座標形式
・極座標形式
別々の表現形式で作成されているライブラリを元に議論を進める。
各表現形式について real-part, imag-part, magnitude, angle という四つの選択子が実装されている。
この時点で、どちらの表現形式でも add-complex, sub-complex, mul-comples, div-complex は正常に動作することが保証される。
2.4.2 タグつきデータ
複数の表現形式を一まとめに扱う場合、それぞれを区別する必要がある。そのために、データにタグ付けをおこなう。
タグを管理するために attach-tag, type-tag, contents を定義する。
つけられたタグを元にどの手続きを使用してデータの処理をおこなうか振り分けるための、窓口になる関数を用意する。
2.4.3 データ主導プログラミングと加法性
型による振り分け:データの型を調べて適切な手続きを呼ぶ一般的戦略
2.4.2のような振り分け実装には幾つか弱点がある
・汎用インターフェース手続きは異なるすべての表現を知らなければいけない
・システム全体でどの手続きも同じ名前を持たないという保証をしなければいけない
→加法的ではない
システム設計を更に部品化する手段→データ主導プログラミング
型と演算を表にし、型から必要な演算を参照できるようする
put/get 手続きを用いてテーブルへの登録とテーブルからの参照ができると仮定して、実際の手続きと対応内容をひとまとまりにしたパッケージを定義する。
apply-generic は演算の名前と引数の型から必要な手続きを探し、作用させる。
※前述のパッケージで、put 時に引数の型をリストで渡していたり apply-generic の type-tags 変数で引数の型タグをリストとして取得しているのは、後から add や sub のような複数の引数を渡す演算に対応するため。
メッセージパッシング
今日の復習はここまで。明日は 2.5 汎用演算のシステムから。