2011-12-31 5 views
4

対のリストを定義します。スキームIスキームで起こる何かのinterstingを把握しようとするシンボル

(define last-pair 
    (lambda (x) 
     (if (null? (cdr x)) 
      x 
      (last-pair (cdr x))))) 

私はこのようにfooの定義された:3回

(define foo 
    (lambda() 
    (let ((s (list 'he 'said:))) 
     (set-cdr! (last-pair s) 
       (list 'ha 'ha)) 
     s))) 

と実行FOOを、I得た:

(he said: ha ha) 
(he said: ha ha) 
(he said: ha ha) 

しかし、私はこのようにfooの定義:

(define foo 
    (lambda() 
    (let ((s '(he said:))) 
     (set-cdr! (last-pair s) 
       (list 'ha 'ha)) 
     s))) 

とのfooを3回実行して、私が得た:

(he said: ha ha) 
(he said: ha ha ha ha) 
(he said: ha ha ha ha ha ha) 

しかし、なぜ?私の最初の考えは、最初にfooに新しいリストを作成し、2番目には新しいリストを作成しないことでした。しかし、私はそれがいかに機能しているか理解していませんでした。 2番目のfooでアドレスを定義し、何をするか? 2番目のfooにもリストとして定義されていますか?またはシンボル?

ありがとうございました。

+0

あなたはどのSchemeの通訳者を使用していますか?私はラケットでその振る舞いを再現できませんでした。なぜなら '(abc)構文は不変のリストを生成するので、常に変更可能なリストを作成するために 'mlist'を使用する必要があるからです。 –

+0

@ÓscarLópez:Dr.SchemeまたはchezSchemeを使用します –

+0

古いバージョンではRacketと呼ばれていますが、他の多くの新機能の中でも、リストが明示的に変更可能であると宣言されていない限り、リストの変更は禁止されています。多分あなたはバグを見つけましたか?あまりに面倒でないならラケットを試してみることをお勧めします –

答えて

3

リテラルリスト((list 'foo 'bar 'baz)とは対照的に、'(foo bar baz))は、not allowed to be mutatedです。そうした場合、「エラーです」(つまり、動作は定義されていません)。

このケースでは、文字通り'(he said:)が何度も再利用されていることに気づいていますが、それは変更されることはないということを理解しています。あなたがその理解に違反したので、あなたは見た奇妙な行動を得る。

対照的に、(list 'he 'said:)を使用すると、毎回新しいリストが返されます。

関連する問題