我有以下计划程序:
(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>)
我目前对如何构建这对的理解是:
c
) 是在调用 call/cc
时创建的。此时,x
是#f
,尚未被评估为cons
的第二个参数。lambda
的 call/cc
期间,x
设置为非 false(连续)值。call/cc
自然返回,不返回任何内容(#!void
),并且x
是从之前设置的调用中检索的。cdr
检索该延续时,我会 expect 恢复创建延续时已知的 x -> #f
的地图。然后,由于 lambda
的 call/cc
主体不会第二次运行,因此 x
将保持为 false。x
将在call/cc
之后进行评估,这次是#f
,导致第二个display
的cdr
不同,并且cdr
的第二次调用失败。然而,真正发生的是,当重新输入延续时,会记住
x
的先前值。为什么,又如何? Scheme实际上使用什么机制来记住环境?
“我希望恢复
的地图(在创建延续时已知)”x -> #f
不。一切都没有恢复。
x
是一个绑定,局部于 let
形式。它有价值。不管它有什么价值,那就是它的价值。不会记住先前的值,只会保留其当前值,位于内存中绑定所指向的位置。
第一个调用将
x
的值设置为 "first"
。该对的 car
仍然保持与之前相同的值 - 相同的延续。
第二次调用时,将
x
的值设置为2
。这意味着什么?这意味着 x
绑定所指的内存位置发生了突变、更改、更改,现在保存了值 2
。