1

私が使用しているプラ​​ットフォームは DrScheme です。

(a b)[によって構築された]ペア(cons a b)は、次のような手順のように言語内で実装されていることがわかりました。

(define (cons a b)
  (lambda(pick)
    (cond ((= pick 1) a)
          ((= pick 2) b))))

そしてセレクター:

(define (car x) (x 1))
(define (cdr x) (x 2))

次に、 のような式で作成されたリストがあります(cons a (cons b (cons c (cons ...))))

今、私が理解しようとしていたのはこれです(DrSchemeのプロンプトで入力):

> (define l1 '(a b c))
> (define l2 (list 'a 'b 'c))
> l1
(a b c)
> l2
(a b c)
> (eq? l1 l2)
#f

わかりました、l2 は単なるリスト (つまり、手順など...) であり、私が先に説明したように、しかし... l1 とは何ですか? シンボル?キャラの並び?それが何であれ、言語内でどのように実装されていますか? ありがとう!

4

3 に答える 3

3

l1同じ要素を含む単なるリストでもあります。これも返すことに注意してください#f

(define l1 '(a b c))
(define l2 '(a b c))
(eq? l1 l2)

これが返される間#t

(define l1 '(a b c))
(define l2 (list 'a 'b 'c))
(equal? l1 l2)

その理由は、とがメモリ内の同じオブジェクトへの参照であるeq?かどうかをチェックし、それらが同じ内容を持っているかどうかをチェックするためです。l1l2equal?

于 2010-06-27T21:27:09.140 に答える
1
> > (define l1 '(a b c))
> > (define l2 (list 'a 'b 'c))
> > l1 (a b c)
> > l2 (a b c)
> > (eq? l1 l2)
> #f

わかりました、l2 は単なるリスト (つまり、手順など...) であり、私が先に説明したように、しかし... l1 とは何ですか? シンボル?キャラの並び?それが何であれ、言語内でどのように実装されていますか? ありがとう!

定義の形式は次のとおりです。

(定義 <名前> <式>)

実行時に式 <expression> が評価され、結果が値になります。その値はメモリのどこかに保存されます。この値を他の計算で使用するには、名前 <name> を使用できます。用語は、<name> が値にバインドされているということです。

注意すべき重要なことは、名前 <name> はソース コードにのみ表示されるということです。実行時には存在しません。したがって、名前 l1 がシンボルかどうかを尋ねても意味がありません。

コンパイラが変換する (<name> <expression> を定義する) ための 1 つの可能な戦略は、次のとおりです (Scheme 実装にガベージ コレクションがあることを無視します)。

  1. ポインタ p 用にメモリセル m を確保する
  2. の値 v を計算する出力コード
  3. v を含むメモリ セルのアドレスをメモリ セル m に格納します。

名前 <name> はこのリストに表示されないことに注意してください。

于 2010-06-30T13:47:12.613 に答える
1

リストはアトムではありません。ここが重要な部分です。シンボルはアトムですが、つまり、それらが同じ場合、それらは同じメモリに常駐し、数値に似ており、実際にはポインターとして見ることができます。シンボルも可変ではありません。シンボルfooは数値のようなもの3です。

ただし、リストはアトム、2 つのリスト、または文字列ではありません。同じ内容を持つベクトルの 2 つの異なる場所に非常によく常駐できます。

eq?メモリの場所のみをテストします。eqv?それが何であるかはあいまいであり、実装に依存します.Scheme標準はこれに対してかなり寛大です.少なくともeq?基本的にのスーパーセットでなければならないと言っているだけです. equal?一方、構造的等価性をテストし、再帰的にテストするため、非常にコストのかかる操作であり、識別子として文字列よりもシンボルが好まれることが多いのはそのためです。

(define l1 (list 1 2 3))
(define l2 (list 1 2 3))
(eq? l1 l2) ; ===> #f in most implementations
(equal? l1 l2) ; ===> #t in all implementations
(eqv? l1 l2) ; ===> #t in some implementations
(define l3 (cdr l1))
(define l4 (cdr l1))
(eq? l3 l4) ; ===> #t, this means that they 'share memory', if you change l3 or l4, l1 will change with it, beware. This is how car and cdr work, they do not copy.
(define l6 (cons 1 l4));
(eq? l1 l6) ; ===> #f again, cons does allocate new memory, but the tails may very well share it, s in this case, l6 does share its tail with all lists except l2 here in memory. 

また、ちょっとした用語です。cons はペアを作成します。これは 2 つの要素のリストとは異なります。ペアを作成します(a . b)。リスト(a b)は実際にはペアと同じです。(a . (b . ()))

また、cons と car と cdr はプリミティブです。以下に示す実装は、コンピュータ プログラムの構造と実装のデモンストレーションであり、それらは厳密には必要ないことを示していますが、それらをプリミティブとして使用するとパフォーマンスが劇的に向上します。 cons、car、および cdr を定義します。

于 2010-06-27T23:11:39.657 に答える