Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme SICP第3.1.1节-程序中的本地状态似乎不一致_Scheme_Closures_State_Sicp - Fatal编程技术网

Scheme SICP第3.1.1节-程序中的本地状态似乎不一致

Scheme SICP第3.1.1节-程序中的本地状态似乎不一致,scheme,closures,state,sicp,Scheme,Closures,State,Sicp,我正在通过SICP工作。我正在看当地的情况。我正在GNU Guile v2.0.11中评估这些练习 我确实找到了答案,但它似乎没有解决我正在努力解决的问题,或者我过于迟钝 我看到的两个例子是: (定义新的提取) (让((余额100)) (λ(金额) (如果(>=余额金额) (开始(设置!余额(-余额金额)) (余额) “资金不足”) (定义(提取余额) (λ(金额) (如果(>=余额金额) (开始(设置!余额(-余额金额)) (余额) “资金不足”)) 将第一个变量指定给变量时,使用: (定义

我正在通过SICP工作。我正在看当地的情况。我正在GNU Guile v2.0.11中评估这些练习

我确实找到了答案,但它似乎没有解决我正在努力解决的问题,或者我过于迟钝

我看到的两个例子是:

(定义新的提取)
(让((余额100))
(λ(金额)
(如果(>=余额金额)
(开始(设置!余额(-余额金额))
(余额)
“资金不足”)
(定义(提取余额)
(λ(金额)
(如果(>=余额金额)
(开始(设置!余额(-余额金额))
(余额)
“资金不足”))
将第一个变量指定给变量时,使用:

(定义新的提款)
(定义b新提取)
我得到两个指向同一过程对象的指针,它们之间共享状态:

scheme@(欺骗用户)>a
$1 = #
方案@(欺诈用户)>b
$2 = #
方案@(欺诈用户)>(a 50)
$3 = 50
方案@(欺诈用户)>(b 10)
$4 = 40
但是,当我实现第二个过程时,我会得到指向两个具有不同状态的不同过程对象的指针:

scheme@(欺骗用户)>(定义c(使退出100))
方案@(欺诈用户)>(定义d(使撤销100))
方案@(欺诈用户)>c
$5 = #
方案@(欺诈用户)>d
$6 = #
方案@(欺诈用户)>(c 50)
$7 = 50
方案@(欺诈用户)>(d 10)
$8 = 90
我已经通读了这一部分,没有明确的解释,当我搜索这一部分时,我很难找到任何东西。一般来说,我理解在状态方面发生了什么,但我不明白这些过程之间的区别是什么,它们允许一个拥有一个通用状态,而另一个保持局部状态


为什么第一个定义“new-draw”无法跨多个任务维护本地状态?似乎每次我们进行不同的分配(定义新的提取)时,lambda都应该捕获余额分配到100

原因是,在第二个示例中,每次都返回一个新的闭包,而在第一个示例中,只有一个闭包,因此只有一个状态

如果您希望在第一种情况下的行为与在第二种情况下的行为相同,请更改为:

(define (new-withdraw) ; this is a procedure now
  (let ((balance 100))
    (lambda (amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))))

(define a (new-withdraw)) ; called as a procedure
(define b (new-withdraw))
然后


我想解释一下,看看我的理解是否正确:在原始示例中,
(定义新收回…
闭包属于主体,
(let(……funds”)))
。这意味着新收回类似于OOP中对象的实例,我只是使用了
(定义…)的别名
s我用过。当你在回答中重新定义它时(定义(新收回)…关闭现在属于新收回本身。现在(新收回)是一个对象的构造函数,a和b是独立的实例。这本质上正确吗?@greggyb是的,基本正确。如果您将其写成
(定义make-draw(lambda(balance)(lambda(amount)…
),那么就不会那么神秘了,直到您对较短的符号感到满意为止。
> (a 50)
50
> (b 10)
90