2011-05-14 16 views
2

環境はスキームの継続の一部ではありませんか?環境は継続の一部ではありませんか?

私はチキン、ゴーシュ、ラケットとギャンビットでこれをテストしており、それらのすべてが同様に振る舞う:LETが評価されたとき、私は-3期待するが、通話中3はKONTする

(define kont #f) 

(let ((a 1) 
     (b 2)) 
    (call-with-current-continuation 
    (lambda (k) 
    (set! kont k) 
    (display 'mutating) 
    (newline) 
    (set! a -1) 
    (set! b -2))) 
    (display (+ a b)) 
    (newline)) 

を(私は)プログラムは、変異前とBのバインディングを覚えているだろうと思ったので、:

(let ...) ; <-- evaluating the LET above 
; prints "mutating" 
=> -3 
(kont 100) 
=> -3 
(kont 100) 
=> -3 

ので継続は制御だけではなく、環境に影響を与えますか?この場合、継続を実装する方法の1つが「スタックをコピーする」ことになっているのはなぜですか(バインディングはスタック上にありません)。

+0

または継続は環境とバインディングを運ぶことになりますが、これらは*変更可能ですか? – josh

答えて

3

続きは、バインディングをキャプチャします。しかし、あなたが推測するように、これらのバインディングは変更可能です。

ここでは、「スタックをコピーする」というスローガンが間違っています。これはcall/ccについて考えるには合理的な方法ですが、それはすべての話ではありません。 1つは、ローカルバインディングがスタックに割り当てられているかどうかを公開する言語機能が本当に必要ないということです。

代わりに、/ ccの呼び出しは、「プログラムコンテキスト」という概念を使用して定義されています。これをうまく処理するには、Shriram Krishnamurthiの(無料、オンライン)教科書PLAI、または(非自由で、はるかに詳細な)書籍「Semantics Engineering with PLT Redex」をご覧ください。

脇に;キャプチャされた継続を決して呼び出さなかったので、あなたのプログラムはあなたがチェックしたいものを本当にチェックしません。私はあなたが次のようなものを書こうと思っていたと思います。

#lang racket 

(define kont #f) 

(let ([a 3]) 

    (let/cc k 
    (set! kont k) 
    (set! a 4)) 
    (printf "~s\n" a)) 

(kont) 

...これは、あなたが上で述べたのとほとんど同じ動作を示しています。

1

環境内のaとbの値を、 !したがって、aとbは連続環境では-1と-2です。副作用を展開することはできません。あなたの継続では、a、b、kontに違いはありません。

関連する問題