Chapter 2 データ型 - 2.2 合成データ型 - 2.2.3 ドット対とリスト

さぁ、耳慣れぬ言葉が出てきました。「ドット対」ですってよ。読みは「どっとつい」ですよね。対消滅みたいな。「リスト」も私の認識は曖昧だなぁ。大事そうなのでゆっくりいきますよ。

ドット対は二つの任意の値を組合せて順序対にすることで作りだされた合成値です。

ん? ハッシュみたいなものか? 2値リストというか。

最初の要素はcar、二番目の要素は cdrと呼ばれ、組合せの手続きはconsです。

でたぁー、car, cdr, cons! なぞの略称だな。


"car cdr cons 由来" でググって見ましたよ。I'm feeling lucky!

car
Contents of the Address part of the Register
cdr
Contents of the Decrement part of the Register
cons
construct

ですか、ほほう。address は良いとして decrement が掴めないな。ハードウェア詳しい人教えてくだちぃ。

gosh> (cons 1 #t)
(1 . #t)
gosh> '(1 . #t)
(1 . #t)

ふんふん。cons 関数使うか、ドットで区切ってクォートして作るのね。
ドット&クォートの方が良く使いそうだな。短いし。

gosh> (define x (cons 1 #t))
x
gosh> (car x)
1
gosh> (cdr x)
#t

car で前の方にアクセス。cdr で後の方にアクセス。


変更はおなじみ set と ! の付いた名前。

gosh> (set-car! x 2)
#<undef>
gosh> x
(2 . #t)
gosh> (set-cdr! x #f)
#<undef>
gosh> x
(2 . #f)


car や cdr にドット対を入れられる。

gosh> (define y (cons (cons 1 2) 3))
y
gosh> y
((1 . 2) . 3)

cdr がドット対のデータ構造の利用方法はイメージできないこともないけど、car の方はわかんないなぁ。「オラすっげぇワクワクしてきたぞ。」


段数を多くしてみよう:

gosh> (define z '('('('('('(1 . 2) . 3) . 4) . 5) . 6) . 7))
z
gosh> z
('('('('('(1 . 2) . 3) . 4) . 5) . 6) . 7)

ん?変だな?

gosh> (define z '((((((1 . 2) . 3) . 4) . 5) . 6) . 7))
z
gosh> z
((((((1 . 2) . 3) . 4) . 5) . 6) . 7)

クォートは一個でいいのか。「保留」みたいな感じかな?

gosh> (car (car y))
1
gosh> (cdr (car y))
2

ふむふむ、内側から評価すれば良いんだね。


省略記法:

gosh> (caar y)
1
gosh> (cdar y)
2

ちょっと寝不足頭にはきついです。「ワイ(お前)かぁア!?」「クダァア!?ワイ」みたいな。
パッと書けるようになるでしょうか? 評価順序と書き順が違うので心配です。

c...rスタイルの省略形は4段のカスケードまでは存在することが保証されています。つまり、cadr、cdadr、cdaddrはいつでも使えます。cdadadrは頑張ってるかもしれません。

ほうほう。では早速:

gosh> (define z (cons (cons (cons (cons (cons (cons 1 2) 3) 4) 5) 6) 7))
z
gosh> z
((((((1 . 2) . 3) . 4) . 5) . 6) . 7)
gosh> (caaaaaar z)
*** ERROR: unbound variable: caaaaaar
Stack Trace:
_______________________________________
gosh> (caaaaar z)
*** ERROR: unbound variable: caaaaar
Stack Trace:
_______________________________________
gosh> (caaaar z)
((1 . 2) . 3)

Gauche は標準の4段カスケードまで、と。


次は cdr が多段の場合。

gosh> (cons 1 (cons 2 (cons 3 (cons 4 5))))
(1 2 3 4 . 5)
gosh> '(1 2 3 4 . 5)
(1 2 3 4 . 5)

な、報われない! こんな略記法があるなんて!


逆もいける?

gosh> '(1 . 2 3 4 5)
*** READ-ERROR: Read error at "(stdin)":line 36: bad dot syntax
Stack Trace:
_______________________________________
gosh> 4
gosh> 5
gosh> *** READ-ERROR: Read error at "(stdin)":line 36: extra close parenthesis
Stack Trace:
_______________________________________

ムリスwwww


今日はここまで。