1

スキームの '(()) と (cons null null) の違いについて混乱しています。

以下のコードは、bcが完全に同じであることを示しています。

(define (dup2 x)
  (let ((d '(())))
    (set-car! d (car x))
    (set-cdr! d (cdr x))
    d))

(define a '(1 2))

(define b (dup2 a))
(define c (dup2 a))

(set-car! b 2)

> c  ;; --> (2 2)

ただし、dup代わりに使用するとdup2

(define (dup x)
  (let ((d (cons null null)))
    (set-car! d (car x))
    (set-cdr! d (cdr x))
    d))

(define a '(1 2))

(define b (dup a))
(define c (dup a))

(set-car! b 2)

> c  ;; --> (1 2)

変数bcは異なります。いくつかの実験を行いましたが、まだ理解できていません。

4

3 に答える 3

0

最初のコード スニペット(d '(()))では、最終的にリテラルを にバインドするを使用しdます。次に、通常未定義のリテラルを変更します。2 番目のコード スニペットでは、新しく作成された「コンス セル」に(d (cons null null))バインドするものを使用し、それを変更します。dそれを変更しても問題ありません。

注: を定義していませんnull。おそらく、'()?

于 2013-10-03T14:03:38.430 に答える
0

のようなデータ リテラルは'(())読み取り専用であり、set-car!またはを使用して変更するとset-cdr!動作が未定義になります。予測可能な動作のために、または(cons '() '())使用する場合はバージョンを使用してください。set-car!set-cdr!

特に、cons新しいコンス セルを作成しますが、データ リテラルは通常そうしません。

それでも、 を実装する目的でdup、なぜandを使用しているのですか? 直接使用するだけです:set-car!set-cdr!cons

 (define (dup x)
   (cons (car x) (cdr x)))
于 2013-10-03T14:02:20.737 に答える