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

- 作者: M.D. ConradBarski,Conrad Barski,川合史朗
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/02/23
- メディア: 大型本
- 購入: 1人 クリック: 18回
- この商品を含むブログ (19件) を見る
前回の記事の続き。
今回の記事では、lambda
とlist
周りについてやっていく。
lambda
lambdaを使うと、名前を与えずに関数を作れる。
例えば、渡した数を半分にする関数。
(defun half(x) (/ x 2)) ;; これを埋め込む。これは、halfという関数を、無名化したもの。 (lambda (n) (/ n 2)) ;; これを実行すると、以下のようになる。 (mapcar (lambda (n) (/ n 2)) '(2 4 6)) ;; (1 2 3)
これがマクロ
lambdaはlispの中で特に大事らしい。
説明がかなり細かく書いてあったが、今の自分にはその重要性を身を以て実感することができていないため、ここでは省略する。
List
Lispにおいて、Listは、Linked Listのような構造をしている。
前にも書いたかもしれないが、リストは、その一個一個がコンスセルとなっている。
一個のコンスセルには、2つの要素がある。
一個目は、その値自身。二個目は、次の要素へのアドレスのようなもの。
2個目の要素がnil
だった場合、その要素はリストの終端を意味している。
また、最後の要素を、nilではなく、リストの先頭に指定することもできる(循環リスト)
しかし、これは要素数が無限になるので、そのままだとREPL
が混乱する。
これを避けるために以下の手続きをとる。
;; 通常のList (cons 1 (cons 2 (cons 3 nil))) ;; (1 2 3) (defparameter foo (list 1 2 3)) ;; 末尾の情報、本来nilになるべきところを、先頭の要素に向ける。 ;; これをする際は、以下のコマンドを叩いて、REPLにそういうことをすることを知らせておかないといけない。 (setf *print-circle* t) (defparameter foo (list 1 2 3)) ;; 最後の要素に、fooを代入 (setf (cdddr foo) foo) ;; 要は、(1 2 3)というのは、 (cons 1 (cons 2 (cons 3 nil))) ;; となっていて、そのnilに、fooを代入しているということ
alist
コンスセルから作られるもののデータ構造の中でも、特に便利なのは、連想リスト、別名alist
と呼ばれるもの。
例えば以下の例では、それぞれの人のコーヒーの注文を表している。
(defparameter *drink-order* '( (bill . double-espresso) (lisa . small-drip-coffee) (john . medium-latte)))
このalist
から、要素を探すには、assoc
を使う。
(assoc 'lisa *drink-order*) ;; (LISA . SMALL-DRIP-COFFEE) (push '(lisa . large-mocha-with-whipped-cream) *drink-order*) (assoc 'lisa *drink-order*) ;; (LISA . LARGE-MOCHA-WITH-WHIPPED-CREAM)
また、assoc
では、最初の一つの要素のみを、見つけてくる。(上の例でわかる)
今回は、以上。
次回は、グラフを作る処理の要点をまとめる。