> (cons 2 3)
(2 . 3)
Lisp 環境では、2 つの項目を接続するために 1 つのコンス セルのみを割り当てる必要があります。
上は Lisp の本 "Land of Lisp" からのものです。このペアが 1 つのコンス セルにのみ配置されている理由がわかりません。このデータのメモリはどのように見えますか?
> (cons 2 3)
(2 . 3)
Lisp 環境では、2 つの項目を接続するために 1 つのコンス セルのみを割り当てる必要があります。
上は Lisp の本 "Land of Lisp" からのものです。このペアが 1 つのコンス セルにのみ配置されている理由がわかりません。このデータのメモリはどのように見えますか?
consセルは、とと呼ばれる2つの値を常に保持しcar
ますcdr
。
+-----+-----+
| car | cdr |
+-----+-----+
consセルを表すために、Lispには「ドット表記」があります。
(car . cdr)
この関数cons
は、次の2つの引数からこのようなconsセルを作成します。
(cons 1 2)
=> (1 . 2)
これは次のように考えることができます:
+-----+-----+
| 1 | 2 |
+-----+-----+
consセルの値は、他のものへの「参照」または「ポインター」にすることもできます。これらの他のものは、たとえば、他の短所セルである可能性があります。
+-----+-----+ +-----+-----+
| 1 | ------->| 2 | nil |
+-----+-----+ +-----+-----+
これは(1 . (2 . nil))
ドット表記になります。この連鎖は、リストを表すためにLispで使用されます。リストはコードの表現に使用されるため、Lispにとって重要です。したがって、それらには短い表記法があります(1 2)
。
CONSセルは、2つのフィールドを持つレコードです。
多くのLisp実装では、consセルに特別な最適化があります。典型的なものは、fixnum番号がポインタなしでフィールドに直接格納されることです。データがメモリに収まる限り、データを直接保存できます。これは、たとえば文字の場合にも当てはまります。文字がフィールドにエンコードされるように、2文字のconsセルを格納することもできます。
他のより大きなデータでは、consセルに格納されているそのデータへのポインタがあります。
次に、次の違いにも注意してください。
(cons 1 2)
と
(list 1 2)
(cons 1 2)
単一のconsセルを作成します。(list 1 2)
2つの短所セルを作成します。最初のconsセルには、1と2番目のセルへのポインターが含まれています。2番目のconsセルには、2とNIL(リストマーカーの終わり)が含まれています。
したがって、最適化として、多くの場合、キーと値のペアでは、リストではなくconsセルのみを使用します。
((age . 22) (name . "Barbara))
対。
((age 22) (name "Barbara"))
後者はさらに2つの短所セルを使用します。
記憶は幻想です:
(define (cons a d)
(lambda (f) (f a d)))
(define (car x)
(x (lambda (theCar theCdr) theCar)))
(define (cdr x)
(x (lambda (theCar theCdr) theCdr)))
ほらママ、記憶は要らない!
(冗談だ)
I think what's the cons in lisp is something like ( just for explanation, not the real code)
typedef struct _cons
{
void* car;
void* cdr;
} cons;
That's what the "single cons" means.