コンピュータ プログラミングにおいて、cons( / ˈ k ɒ n z /または/ ˈ k ɒ n s / ) は、Lispプログラミング言語のほとんどの方言における基本的な関数です。 const は、 2 つの値または 2 つの値へのポインターを保持するメモリ オブジェクトを構築します。これらのオブジェクトは、(cons) セル、cons、非アトミックS 式("NATS")、または (cons)ペアと呼ばれます。Lisp の専門用語では、"to cons x onto y " という表現は、を使用して新しいオブジェクトを構築することを意味します。結果のペアには、 ( レジスタ のアドレス部分の最初の要素または内容) と呼ばれる左半分と、(レジスタのデクリメント部分の最初の要素または内容)と呼ばれる右半分
があります。cons (cons x y)carcdr
これは、引数を指定して新しいオブジェクトを作成するオブジェクト指向の概念であるコンストラクターと大まかに関連しており、より密接には代数データ型システムのコンストラクター関数に関連しています。
「cons」という単語や「to cons onto」などの表現も、より一般的な関数型プログラミングの専門用語の一部です。特にリスト処理のコンテキストでは、同様の目的を持つ演算子が「cons」と発音されることがあります。(良い例としては、ML、Scala、F#、Lean、Coq、Elm::の演算子や、リストの先頭に要素を追加する
Haskellの演算子があります。):
使用
コンスセルは順序付けられたデータのペアを保持するために使用できますが、より複雑な複合データ構造、特にリストやバイナリツリーを構築するために使用されることが一般的です。
順序付きペア
たとえば、Lisp 式は、左半分 (いわゆるフィールド) に 1、右半分 (フィールド) に 2 を保持するセルを構築します。Lisp 表記では、値は次のようになります。
(cons 1 2)carcdr(cons 1 2)
(1.2)
1 と 2 の間にあるドットに注意してください。これは、S 式が「リスト」ではなく「ドット ペア」(いわゆる「コンス ペア」) であることを示しています。
リスト

cons:(定数42 (定数69 (定数613なし)))
list:(リスト42 69 613 )
Lisp では、リストはコンス ペアの上に実装されます。より具体的には、Lisp のリスト構造は次のいずれかです。
- 空のリスト
()。これは通常 と呼ばれる特殊なオブジェクトですnil。 carリストの最初の要素であり、残りの要素を含むリストcdrであるコンス セル。
これは、、、を使用して内容を操作できる、単純な単方向リンク リスト構造の基礎となります。は、cons ペアではない唯一のリストであることに注意してください。例として、要素が 1、2、3 であるリストを考えてみましょう。このようなリストは、次の 3 つの手順で作成できます。
conscarcdrnil
- 3 を
nil、空のリストに結合します - 結果に対する短所2
- 短所1 結果
これは次の単一の式と同等です。
(コンス1 (コンス2 (コンス3 nil )))
またはその省略形:
(リスト1 2 3 )
結果の値は次のリストになります。
(1 . (2 . (3 . ゼロ)))
つまり
*--*--*--なし | | | 1 2 3
一般的には次のように略されます。
(1 2 3)
したがって、cons既存のリンク リストの先頭に 1 つの要素を追加するために使用できます。たとえば、x が上で定義したリストである場合、次のリストが生成されます。
(cons 5 x)
(5 1 2 3)
もう 1 つの便利なリスト プロシージャはappendです。これは、既存の 2 つのリストを連結します(つまり、2 つのリストを 1 つのリストに組み合わせます)。
木々
葉にのみデータを格納するバイナリ ツリーも、 で簡単に構築できますcons。たとえば、次のコードです。
(短所(短所1 2 ) (短所3 4 ))
ツリーの結果:
((1 . 2) . (3 . 4))
つまり
* / \ * * / \ / \ 1 2 3 4
技術的には、前の例のリスト (1 2 3) もバイナリ ツリーですが、特に不均衡な状態になっています。これを確認するには、図を並べ替えるだけです。
*--*--*--なし | | | 1 2 3
次のように同等になります。
*
/ \
1 *
/ \
2 *
/ \
3 0
会話で使う
欠点は、命令型プログラミング言語で使用されるような破壊的な操作を使用するのではなく、メモリ割り当ての一般的なプロセスを指す場合があります。 [引用が必要]例:
ばかげた欠点を付ける代わりに副作用を入れることで、コードを少し高速化しました。
機能実装
Lisp には第一級関数があるため、コンスセルを含むすべてのデータ構造は関数を使用して実装できます。たとえば、Schemeでは次のようになります。
(定義( cons x y ) ( lambda ( m ) ( m x y ))) (定義( car z ) ( z ( lambda ( p q ) p ))) (定義( cdr z ) ( z ( lambda ( p q ) q )))
この手法は、チャーチ エンコーディングとして知られています。これは、関数を「コンス セル」として使用して、 cons、car、およびcdr操作を再実装します。チャーチ エンコーディングは、Scheme に密接に関連する抽象的で理論的な計算モデルである純粋なラムダ計算でデータ構造を定義する一般的な方法です。
この実装は学術的には興味深いものですが、コンス セルを他の Scheme プロシージャと区別できなくなり、不必要な計算の非効率性も生じるため、実用的ではありません。
しかし、同じ種類のエンコーディングは、バリアントを持つより複雑な代数データ型にも使用でき、他の種類のエンコーディングよりも効率的であることが判明する場合もあります。[1]このエンコーディングには、ラムダの代わりにインターフェースを使用して、 Java などのバリアントを持たない静的型付け言語で実装できるという利点もあります。
参照
参考文献
- ^ 「データ型とパターンを関数に変換することで効率的に解釈する」(PDF) 。2010年 3 月 31 日のオリジナル(PDF)からアーカイブ。2009年 3 月 1 日に取得。
外部リンク
- SDRAW は、 コンス セル構造を描画するためのCommon Lispコードです。David S. Touretzky 提供。
