简体   繁体   English

关于“框架作为本地状态的存储库”

[英]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: balancebody: (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM