call/cc 可变环境存储

问题描述 投票:0回答:1

我有以下计划程序:

(define sg-pair (let ()
                  (define x #f)
                  (cons
                   (call/cc (lambda (c)
                              (set! x c)))
                   x)))

(display sg-pair)
(display "\n")

(if (eq? (car sg-pair) (void))
    (let ()
      ((cdr sg-pair) "first")))

(if (string? (car sg-pair))
    (let ()
      ((cdr sg-pair) 2)))

这将打印以下内容:

(#!void . #<procedure #2>)
(first . #<procedure #2>)
(2 . #<procedure #2>)

我目前对如何构建这对的理解是:

  1. 延续 (
    c
    ) 是在调用
    call/cc
    时创建的。此时,
    x
    #f
    ,尚未被评估为
    cons
    的第二个参数。
  2. 在执行传递给
    lambda
    call/cc
    期间,
    x
    设置为非 false(连续)值。
  3. call/cc
    自然返回,不返回任何内容(
    #!void
    ),并且
    x
    是从之前设置的调用中检索的。
  4. 当稍后通过
    cdr
    检索该延续时,我会 expect 恢复创建延续时已知的
    x -> #f
    的地图。然后,由于
    lambda
    call/cc
    主体不会第二次运行,因此
    x
    将保持为 false。
  5. x
    将在
    call/cc
    之后进行评估,这次是
    #f
    ,导致第二个
    display
    cdr
    不同,并且
    cdr
    的第二次调用失败。

然而,真正发生的是,当重新输入延续时,会记住

x
的先前值。为什么,又如何? Scheme实际上使用什么机制来记住环境?

scheme callcc
1个回答
0
投票

“我希望恢复

x -> #f
的地图(在创建延续时已知)”

不。一切都没有恢复。

x
是一个绑定,局部于
let
形式。它有价值。不管它有什么价值,那就是它的价值。不会记住先前的值,只会保留其当前值,位于内存中绑定所指向的位置。

第一个调用将

x
的值设置为
"first"
。该对的
car
仍然保持与之前相同的值 - 相同的延续。

第二次调用时,将

x
的值设置为
2
。这意味着什么?这意味着
x
绑定所指的内存位置发生了突变、更改、更改,现在保存了值
2

© www.soinside.com 2019 - 2024. All rights reserved.