「CARとCDR」の版間の差分

削除された内容 追加された内容
11行目:
LISPにおいて、コンス(またはペア、またはドット対)は2つの要素を持つ[[順序対]]である。1番目の要素をCAR、2番目の要素をCDRと呼ぶ。リストは「CDRがリストであるコンス、または[[Null|空リスト]]」であると[[再帰的定義|再帰的に定義]]される<ref>COMMON LISP 第2版 p.25。なおCommon Lispでは最後の要素のCDRが空リストでないものは「ドットリスト」と呼ばれてリストとは別扱いされる。</ref>。
 
具体的にいうと、要素 <code><var>a</var></code> <code><var>b</var></code> から構成されるコンスは {{<code|lang=lisp|>(<var>a</var> . <var>b</var>)}}</code> と表され、リスト {{<code|lang=lisp|>(a<var>e<sub>1</sub></var> b<var>e<sub>2</sub></var> c<var>e<sub>3</sub></var>)}}</code> は、各要素を <code>car</code> 関数取り出せところのコンスセルと、後続のコンスセル <code>cdrの鎖</code> 関数つないだ取り出せるところの[[連結リスト|片方向リスト]]、すなわち {{<code|lang=lisp|>(a<var>e<sub>1</sub></var> . (b<var>e<sub>2</sub></var> . (c<var>e<sub>3</sub></var> . (nil))))}}</code> として実現されている。したがって、リストの先頭の要素を得るのは、最後の要素を得るのに比べて効率がよい。
 
リスト <code><var>L</var></code> の2番目の要素は {{<code|lang=lisp|>(car (cdr <var>L</var>))}}</code>、3番目の要素は {{<code|lang=lisp|>(car (cdr (cdr <var>L</var>)))}}</code> のようにして得られる。Common Lispなどの多くのLISP方言では、簡略化するために、{{code|lang=lisp|(car (cdr L))}} と同じことをする {{code|lang=lisp|(cadr L)}} という関数が定義されている。同様に caddr, cadddr なども存在する。
 
関数 <code>car</code> <code>cdr</code> の引数が空リスト <code>nil</code> である場合、Common Lispでは空リストを返す<ref>COMMON LISP 第2版 p.361</ref>。[[Scheme]]ではエラーになる<ref>{{cite book|chapterurl=https://www.scheme.com/tspl4/objects.html#./objects:h3|chapter=Operations on Objects|title=The Scheme Programming Language|author=R. Kent Dybvig|edition=4th|publisher=The MIT Press|year=2009|isbn=978-0-262-51298-5}}</ref>。
 
car/cdrは、consと逆のことをする関数である。すなわち{{code|lang=lisp|(car (cons X Y))}}は X に、{{code|lang=lisp|(cdr (cons X Y))}} は Y に等しい。また、{{code|lang=lisp|(cons (car L) (cdr L))}} は L と構造的には等しい(同じオブジェクトを指すとは限らない)。
 
car/cdrは副作用を持たず、またconsセルも消費しない。
 
== 応用 ==