実践CommonLispを読むその10

第十三章 リストを越えて:コンスセルの別用途

ここではデータ構造に関して説明している。木構造や集合、ルックアップテーブルの説明

木構造LISPでは一番扱いやすそうだし理解しやすい構造だと思う。他の言語と比較しても一目瞭然だ。ただ階層が深くなるとLISPでも、そのリストを見た瞬間にどんな木構造なのかを把握するのは慣れてないと無理だろ。

関数 内容
copy-list リスト構造を複製するが要素は複製しない
copy-tree リスト構造及び要素を複製する
[0]> (defparameter *list-1* '((1 2) (3 4) (5 6))
*LIST-1*
[1]> (setf *list-2* (copy-list *list-1*))
*LIST-2*
[2]> *list-2*
((1 2) (3 4) (5 6))
[3]> (setf (cdr (car *list-1*)) '(99))
(99)
[4]> *list-2*
((1 99) (3 4) (5 6))
[5]> (setf *list-3* (copy-tree *list-1*))
((1 99) (3 4) (5 6))
[6]> (setf (cdr (car *list-3*)) '(2))
2
[7]> *list-1*
((1 99) (3 4) (5 6))
[8]> *list-2*
((1 99) (3 4) (5 6))
[9]> *list-3*
((1 2) (3 4) (5 6))

「copy-list」はコピー元と要素を共有するって事ですね。対して「copy-tree」は要素を共有せずに新しい空間にリスト及び要素を作るって事ですね。

よくわかりました。

集合に関しては良く分かりませんでした。結局リストですよね。で、2つのリストを比べて和集合なのかとかを評価できるって事でいいの?いまいち理解不足。

ルックアップテーブルとは、連想リストと属性リストの事を指す。

[0]> (cdr (assoc 'a ((a . 1) (b . 2) (c . 3))))
1
[1]> (cdr (assoc 'c ((a . 1) (b . 2) (c . 3))))
3
[2]> (cdr (assoc "b" (("a" . 1) ("b" . 2) ("c" . 3)) :test #'string=))
2

キーに対応する値を返すデータ構造。要素がコンスセルになっているリストって事です。これはハッシュテーブルではないが簡易的にデータを格納するやり方としては重宝する。またデータが少量であればなおさらよいらしい。データ量が多くなればハッシュテーブルを使った方がいいって事ですね。ところで本当のハッシュテーブルって、まだ見ていない気がするんだが・・・既に第十一章 コレクションのところで出てきてますね。なんかさらっと流された気がします。

属性リストは属性と値を対応させるデータ構造。

[0]> (defparameter *plist* '(:a 1 :b 2 :c 3))
*PLIST*
[1]> (getf *plist* :a)
1
[2]> (setf (getf *plist* :d) 4)
4
[3]> *plist*
(:D 4 :A 1 :B 2 :C 3)

属性リストは属性を指定する事によって値を取得でき、属性が存在しない場合はエラーにならず、その属性を作成するという特徴がありますね。というか「getf」で属性を取得しようとしてNILが返ってきた場合、新規に属性「:D」を作成し「setf」で「:D」に値を格納するって事かな?「getf」で新しい属性が簡単にできたら困るよね。

[4]> (getf *plist* :e)
NIL
[5]> *plist*
(:D 4 :A 1 :B 2 :C 3)

しかし、新規に属性が作られると先頭になるんだ。

「destructuring-bind」はリストとキー値を対応付けるもの?良くわからん。

[0]> (destructuring-bind (x y z) (list 1 2 3)
       (list :x x :y y :z z))
(:X 1 :Y 2 :Z 3)

まあそんな感じ。長いな、全部読み終わるのはいつになるやら