Land of Lisp 9章を読んだ
8章まで読んですでに忘れていることが多いから復習しようと思ったけど、9章で第Ⅱ部が終わるので読むことにしました。
9章 より進んだデータ型とジェネリックプログラミング
CommonLispで扱える基本的なデータ型に加えてより進んだデータ型がある
配列 - (make-array)
要素を取り出すにはaref関数。値をセットにする時には、arefとsetfを組み合わせる。あと配列はリストよりもアクセスする時間が速い。
(setf (aref [配列名] [要素番号]) '[入れる値])
ハッシュテーブル - (make-hash-table)
ハッシュテーブルはalistと同じようにキーに値を結びつけるけど、alistより速い。要素を取り出すのはgethash関数。格納するときは、やっぱりsetfを使う。
(setf (gethash '[キー] [テーブル名]) '[入れる値])
構造体 - (defstruct)
オブジェクト指向プログラミング言語と同じように、属性(スロット)を持つオブジェクトを表現することができる。構造体はリストとは違って変更可能(mutable)なデータ構造と相性がいい。Lispのリストは一度作ったら変わらないデータ構造のほうがいい。当然だけど、Javaで言う継承みたいなこともできる。
上に出てきたsetfはジェネリックなセッターであり、値を取り出すコードと、値を入れるコードが同じ形で書ける。
次にいくつかの関数が紹介されている。
シーケンス関数
- find-if
- count
- position
- some - シーケンス中に条件を満たす要素が最低一つあるか
- every - シーケンス中に全ての条件を満たす要素があるか
- reduce - シーケンス中の全ての要素を単一の値へと蒸留する
- map - 各要素を引数に渡した関数を読んで結果を集める。ただし、mapcarとは違ってシーケンス型を選択できる。
- subseq
シーケンス関数はもっといっぱいあるらしいです。
型述語 を使ってジェネリック関数を作る(defmethod)
defmethodを使うと、defunと違って引数の型に応じたものを選ぶようにできるらしい。
(defmethod add ( (a number) (b number)) (+ a b)
と
(defmethod add ( (a list) (b list)) (append a b)
の二種類のaddを定義出来る。defunだと出来ない。
以上を使って、「オーク・バトル」というゲームを作る。
http://landoflisp.com/orc-battle.lisp
このゲーム、普通に面白いです。ただテキストの表示が多すぎて全然読む気がしません笑。とりあえず自分の体力だけ見てやってたらそんなに勝てなかった。
まとめ
Lispっぽくないけど使ったらパワーがヤバいみたいなものがいくつも紹介されています。それと、なるべくジェネリックに、型を気にせず書けるようになっているらしい。すごいね。次回は第Ⅰ部と第Ⅱ部の復習します。
追記
はてなの仕様で"(("って書くと注釈になっちゃうんですね。ぐぬぬ。そもそもはてな記法でソースコード貼り付けろって話なので、そうします。