Explaining different behavior of variables referenced in continuations?

冷暖自知 提交于 2019-12-25 03:06:22

问题


Following are two case which have different behaviors regarding the value of i across calls to stored continuations. How can the difference be explained?

Case A

>(define cc #f)
>(define (x)
    (let ((i 0))
    (set! i (+ i 100))
    (+ i (+ i (call/cc (lambda (k) (set! cc k) 1)))) ; call/cc is not included by set!
    (set! i (+ i 10))
    i))
> (x)
110
> (cc 50) ; the context variable i changes as cc calling
120
> (cc 50)
130

Case B

> (define cc #f)
> (define (x)
    (let ((i 0))
    (set! i (+ i 100))
    (set! i (+ i (call/cc (lambda (k) (set! cc k) 1)))) ; call/cc is included by set!
    (set! i (+ i 10))
    i))
> (x)
111
> (cc 50) ; the context variable i always be 0, not changing as cc calling
160
> (cc 50)
160        

回答1:


I'm making assumptions here, so forgive me if I'm wrong :)

I was able to reproduce this in Racket and in my pet Scheme implementation. The problem may hide in the way the continuations are implemented in the specific Scheme implementation. So here are my assumptions:

  • The implementation evaluates the arguments of a procedure from left to right.
  • The resulting values are stored in a stack.
  • The stack is copied when calling call/cc and the copy contains the evaluated procedure arguments.
  • When the continuation is called the copied stack is restored together with the evaluated procedure arguments.

This means that in

(set! i (+ i (call/cc (lambda (k) (set! cc k) 1))))

i in the + application is evaluated before call/cc and its value 100 is stored in the stack. When cc is called it does not reevaluate i and instead uses the value 100, evaluated before. So when calling (cc 50) you get

(set! i (+ 100 50))

If you switch the places of call/cc and i, then i will be reevaluated and thus you get correct results.

(define cc #f)
(define (x)
    (let ((i 0))
    (set! i (+ i 100))
    (set! i (+ (call/cc (lambda (k) (set! cc k) 1)) i))
    (set! i (+ i 10))
    i))
> (x)
111
> (cc 50)
171
> (cc 50)
231


来源:https://stackoverflow.com/questions/26997717/explaining-different-behavior-of-variables-referenced-in-continuations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!