提问人:Enlico 提问时间:1/17/2022 更新时间:1/19/2022 访问量:54
关于“帧作为本地状态的存储库”
About "Frames as Repository of Local State"
问:
SICP,第 3.2.3 节中的练习 3.10 显示了以下内容作为先前定义的替代方法:make-withdraw
(define (make-withdraw initial-amount)
(let ((balance initial-amount))
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
并规定我们
使用环境模型来分析这个替代版本,绘制如上图所示的图形来说明交互
make-withdraw
(define W1 (make-withdraw 100)) (W1 50) (define W2 (make-withdraw 100))
但是,在上述请求之前,文本回顾了 .(let ((<var> <exp>)) <body>)
((lambda (<var>) <body>) <exp>)
现在我想这个建议意味着我应该分析这个版本的:make-withdraw
(define (make-withdraw initial-amount)
((lambda (balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
initial-amount))
或者,甚至更好(基于第 3.2.1 节中的过程定义语法只是底层隐式 lambda
表达式的语法糖):
(define make-withdraw
(lambda (initial-amount)
((lambda (balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
initial-amount)))
在这里,我看到了 3 个 lambda 过程,而在这个和这个解决方案中(非官方的;我不知道官方解决方案)只显示了两个程序。例如,这是后一种解决方案:
; After (define W1 (make-withdraw 100))
global env
------------------
| |<--- env: global env
| | parameters: initial-amount
| make-withdraw: ----> body:
| | ((lambda (balance)
| | (lambda (amount)
| | (if (>= balance amount)
| | (begin (set! balance (- balance amount))
| | balance)
| | "Insufficient funds"))) initial-amount)
| |
| | E1
| | -----------------------
| |<----| initial-amount: 100 |
| | -----------------------
| | /\
| | E2 |
| | ----------------
| | | balance: 100 |
| | ----------------
| | /\
| | |
| | env: E2
| | parameters: amount
| W1: ---------------> body:
| | (if (>= balance amount)
| | (begin (set! balance (- balance amount))
| | balance)
| | "Insufficient funds")
------------------
而我本来会想象一个带有 和 的过程也被绘制出来,因为这是(临时的?)lambda,它运行(绑定到 ,而不是 ,而 又绑定到 in)以生成最终绑定到的过程。parameters: balance
body: (lambda (amount) …)
E2
balance
initial-amount
100
100
E1
W1
我说得对吗?如果没有,你能解释一下原因吗?
答:
当被调用时,它会构造一个绑定到的环境(如图所示)。然后,它立即调用此环境中的另一个函数:该函数构造一个子环境,该子环境绑定到图中的 ,并返回在该环境中定义的第三个函数,因此该函数是 的返回值。(make-withdraw 100)
initial-amount
100
E1
balance
100
E2
make-withdraw
所以现在绑定到第三个函数,其环境是 。构造的第二个函数已被调用并返回其值(第三个函数):它不再出现在图片中。W1
E2
E2
这就是为什么它不再存在的原因。
我不确定它是否有帮助,但如果根本不存在,那么考虑环境图片可能会很有用,因为它实际上只是在点上定义的虚假噪声(显然不是在现实生活中,您可能想做几个帐户!make-withdraw
W1
(define W1 ((λ (initial-amount)
;; this function was `make-withdraw`
((λ (balance)
;; this function was `let`
(λ (amount)
;; this is what W1 will end up being
(if (>= balance amount)
(begin
(set! balance (- balance amount))
balance)
"Insufficient funds")))
initial-amount))
100))
评论