あくまで自分用のメモ。
今後の実装の時に、簡単に振り返るための記事。
進めている本は、Land Of Lisp

- 作者: M.D. ConradBarski,Conrad Barski,川合史朗
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/02/23
- メディア: 大型本
- 購入: 1人 クリック: 18回
- この商品を含むブログ (19件) を見る
前回の記事の続き。
少し順番がおかしいが、今回の記事では、struct
とgeneric
周りについてやっていく。これは、本では9章に書いてある内容。
struct
Lispにも構造体というデータ構造は存在する。
(defstruct person name age waist-size favorite-color)
上のように、構造体を定義できる。
この構造体を利用するには、以下のように、defparameterを用いる。
(defparameter *bob* (make-person :name "Bob" :age 35 :waist-size 32 :favorite-color "blue"))
ここで注目なのが、make-person
のperson
の部分は構造体に合わせて動的に生成される、という点。
動的すぎて、不安になる。
generic
この章で扱うのは、データをgenericに扱うためのもの
例えば、リストか配列に入っている数値のグループを足し合わせたい。
こう言った際に、同じ機能のものを型の違い、つまりデータの取り出し方の違いだけで、複数書かないとダメなのか。となる。
当然そんなことはなく、lispには値をgeneric
に扱うための機構がいくつも用意していある。
例として、ジェネリックライブラリ関数、型述語、defmethod、ジェネリックアクセサなど。
これらの機能を使うと、defstruct
で作られたユーザー定義型に関しても、一つのコードで対応できるようになる。
まず、引数の型によらないコードを書くことを考えるが、この場合は、データのチェックを他の誰かにやってもらうのが楽。
そこで、もっともよく使われるのは、シーケンス関数
そのうちの一つが、length関数。 これはいろんな型を取れる。
これはどういうことかというと、型によって、処理を書き分けることができるようになる、ということ。
例えば、listが渡ってきた場合はその要素数を返すが、文字列が渡ってきた場合、文字数を返す、など。
reduce関数
これらのシーケンス関数の中でも、特に便利なものの一つがreduce関数。
(reduce #'+ '(3 4 6 5 2))
;; これあんまり意味がわからん ;; lambdaに、リストを渡している
(reduce (lambda (best item) ;; 偶数で、かつ、item > bestだった場合 (if (and (evenp item) (> item best)) item best)) '(7 4 6 5 2) :initial-value 0) (defun sum (lst) (reduce #'+ lst)) (sum '(1 2 3)) (sum (make-array 5 :initial-contents '(1 2 3 4 5)))
map
mapは、今までのmapcarとほぼ同じ動作をする。
違いは、前者は、いろいろ受け取れるのに対して、mapcarは、リストしか扱えない
(map 'list (lambda (x) (if (eq x #\s) #\S x)) "This is a string")