[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

learning lisp: cons



さて cons です。cons は普通「コンス」読みます。まず第2引数がリストの場
合について説明します。

第2引数がリストのとき、cons はそのリストの先頭に新しい要素を追加したも
のを返します。評価した結果を => で示すと、

(cons 'x '(a b c)) => (x a b c)
(cons 'y '(x a b c)) => (y x a b c)
(cons 'z nil) => (z) ; nil は () の意味だから
(cons '(a b) '(c d)) => ((a b) c d) ; (a b c d) ではない

となります。最後がちょっとわかりにくいかもしれません。

(cons '(a b) '(c d)) は、(c d) というリストの先頭「要素」として (a b) 
というリストを追加するのであって、(a b) と (c d) という2個のリストを結
合するのではありません。この場合リスト (a b) はあくまで要素の一つです
から、レベルとしてはその後ろの c とか d などのシンボルと同等です。

cons も元のリストには変更を加えません。

(setq my-list '(a b c)) => (a b c)
(cons 'x my-list) => (x a b c)
my-list => (a b c)

ですから、本当に変数の値を変えようと思ったら setq しなくてはいけません。

my-list => (a b c)
(setq my-list (cons 'x my-list)) => (x a b c)
my-list => (x a b c)

次に、cons の第2引数がリストでないときです。この場合 cons は dotted
pair というものを作って返します。dotted pair は一見リストに似ています
が、要素は2個しかなく、かつ真中にピリオドがあります。ピリオドの前後に
は空白が必要です。

(cons 'a 'b) => (a . b)
(cons "Julius" "Caesar") => ("Julius" . "Caesar")
(cons "Caesar" 3) => ("Caesar" . 3)
(cons 'symbol "string") => (symbol . "string")

第1引数がリストで、第2引数がリストでない場合も dotted pair になります。

(cons '(a b) 'x) => ((a b) . x)

引数が dotted pair のとき、car はピリオドの左側を、cdr はピリオドの右
側を返します。

(car '(a . b)) => a
(cdr '(a . b)) => b

(car '(a b)) と (car '(a . b)) はどちらも a で同じになりますが、
(cdr '(a b)) と (cdr '(a . b)) は前者が (b) 、後者が b と別になります
ので注意して下さい。

さて、auto-mode-alist は dotted pair のリストです。つまり単純化すると、
((a . b) (c . d) (e . f) (g . h) ...) という形をしてます。ですからこれ
に新しい要素を追加する場合は、

(setq auto-mode-alist
      (cons (cons なんとか かんとか)
            auto-mode-alist))

と書くことになります。内側の cons で新しく追加する要素となる dotted
pair を作り、外側の cons でそれをリストの先頭に追加します。

ここまでがわかれば、プログラムを書く上で特に不都合はないと思います。

-- 
TAKAHASHI Naoto
ntakahas@...
http://www.m17n.org/ntakahas/