[英]About "Frames as Repository of Local State"
SICP, Exercise 3.10 in section 3.2.3 shows the following as an alternative to a previously defined make-withdraw
: 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"))))
and prescribes that we并规定我们
Use the environment model to analyze this alternate version of
make-withdraw
, drawing figures like the ones above to illustrate the interactions使用环境 model 来分析这个make-withdraw
的替代版本,绘制类似上面的图来说明交互(define W1 (make-withdraw 100)) (W1 50) (define W2 (make-withdraw 100))
However, before the above request, the text recalls that (let (( <var> <exp> )) <body> )
is syntactic sugar for ((lambda ( <var> ) <body> ) <exp> )
.然而,在上述请求之前,文本回忆起(let (( <var> <exp> )) <body> )
是((lambda ( <var> ) <body> ) <exp> )
的语法糖。
Now I guess that suggestion means that I should analize actually this version of make-withdraw
:现在我猜这个建议意味着我应该分析这个版本的make-withdraw
:
(define (make-withdraw initial-amount)
((lambda (balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
initial-amount))
or, even better (based on The procedure definition syntax is just syntactic sugar for an underlying implicit lambda
expression , from section 3.2.1 ):或者,甚至更好(基于过程定义语法只是底层隐式lambda
表达式的语法糖,来自第 3.2.1 节):
(define make-withdraw
(lambda (initial-amount)
((lambda (balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
initial-amount)))
And here I see 3 lambda procedures, whereas in both this and this solutions (unofficial; I don't know of official solutions) only two procedures are shown.在这里我看到 3 lambda 程序,而在这个和这个解决方案(非官方;我不知道官方解决方案)中只显示了两个程序。 For instance, this is the latter solution:例如,这是后一种解决方案:
; 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")
------------------
whereas I would have imagined that a procedure with parameters: balance
and body: (lambda (amount) …)
was drawn as well, as that's the (temporary?) lambda that's run in E2
(with balance
bound to initial-amount
, not to 100
, which is in turn bound to 100
in E1
) to generate the procedure that's ultimately bound to W1
.而我会想象一个带有parameters: balance
和body: (lambda (amount) …)
也被绘制,因为那是在E2
中运行的(临时?) lambda ( balance
绑定到initial-amount
,而不是100
,这反过来又绑定到E1
中的100
)以生成最终绑定到W1
的过程。
Am I correct?我对么? If not, can you explain why?如果不是,你能解释一下为什么吗?
When (make-withdraw 100)
is called it constructs an environment with initial-amount
bound to 100
(this is E1
in the diagram).当(make-withdraw 100)
被调用时,它会构建一个initial-amount
绑定到100
的环境(这是图中的E1
)。 It then immediately calls another function in this environment : that function constructs a child environment in which balance
is bound to 100
, which is E2
in the diagram, and returns a third function defined in that environment, which is thus the return value of make-withdraw
. It then immediately calls another function in this environment : that function constructs a child environment in which balance
is bound to 100
, which is E2
in the diagram, and returns a third function defined in that environment, which is thus the return value of make-withdraw
。
So W1
is now bound to that third function, whose environment is E2
.所以W1
现在绑定到第三个 function,其环境是E2
。 The second function, which constructed E2
, has been called and has returned its value (the third function): it's no longer in the picture.构造E2
的第二个 function 已被调用并返回其值(第三个函数):它不再出现在图片中。
That's why it's not there any more.这就是它不再存在的原因。
I'm not sure if it helps, but it might be useful to think of the environment picture if make-withdraw
didn't exist at all as its really just spurious noise at the point W1
has been defined (obviously not in real life, where you might want to make several accounts:):我不确定它是否有帮助,但是如果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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.