Shammer's Philosophy

My private adversaria

car とか cdar とか cddar とかいろいろ

リストやセルやコンスから決まった箇所のデータを取り出したい、というときに、car や cdr を駆使することになる。car はコンスの左側を取得、cdr はコンスの右側を取得、というのが基本。まあ、これで悩むことはまずない。でも、これらは複雑に絡み合って、caddar とか cdadr とか、パッと見ではどこのデータを取得できるのかよくわからない関数になる。まあ、car や cdr を繰り返している、という意味では単純なのだが、例えば '*1 というコンスに cdar をやるとどの部分が取り出されるか、となるとやってみないとわからなくなってしまう。そして、その原因は(あくまでも個人的な原因だけれども)cdar は cdr をやってから car なのか、car をやってから cdr なのかわからなくなってしまうためだ。というわけで、実際にやりながら考えて理解してみる。

* (cdar '((a b c) (x y z) (0 1 2) (7 8 9)))

(B C)
*

結論は (b c) となった。つまり、これは car が実行されてから、その応答に対して cdr が実行されている。

* (car '((a b c) (x y z) (0 1 2) (7 8 9)))

(A B C)
* (cdr '(a b c))

(B C)
*

文章にすると大変だが、

  1. 関数の最初の c と r を除外し、間の a と d の数をカウント
  2. n 回目の処理では、c + "a と d の羅列の中で右から n 番目のもの" + r を実行
  3. これを a と d の合計数分繰り返す

という感じだろうか。とりあえず、c と r の間は右から繰り返される、と覚えておけばいいだろう。

*1:a b c) (x y z) (0 1 2) (7 8 9