词汇范围和共享对象



考虑 SICP 中的 make-account 过程。

(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin
(set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request: MAKE-ACCOUNT" m))))
dispatch)

和例子:

(define peter-acc (make-account 100))
(define paul-acc peter-acc)

脚注:

单个计算对象被更多访问的现象 一个名称称为别名。联名银行账户情况 说明了一个非常简单的别名示例。

虫子可以 发生在我们的程序中,如果我们忘记了对对象的更改可能会 此外,作为"副作用",更改"不同"对象,因为两者 "不同"对象实际上是出现在下面的单个对象 不同的别名。这些所谓的副作用错误是如此困难 定位并分析一些人提出 编程语言的设计方式不允许 side 效果或混叠

...">

在正常情况下,我会在这里说:"paul-acc指的是peter-acc"。

据我了解,peter-acc 和 paul-acc 实际上是指向一个计算对象的名称。所以它们是一样的。

我对如何在评估的环境模型中对其进行建模感到困惑。例如:

(define (f bank-account) ((bank-account 'deposit) 69))
(define peter-acc (make-account 100))
(define paul-acc peter-acc)
(f paul-acc)

我不能做环境图,因为我的眼睛被毁了。以下是我认为交互应该是:

  • make-account 和 f 具有指向全球环境的指针。
  • (
  • 定义 peter-acc (make-account 100)) 被评估。 make-account 创建一个新环境 E1。封闭环境是全局的。创建内部程序提取,存款和发送,并具有指向e1的指针。调度被返回,并在全局环境中绑定到名称 peter-acc。
  • (定义 paul-acc peter-acc)被评估。名称 peter-acc 位于全局框架中。Paul-ACC 绑定到 E1 中的调度过程对象,因为这是 Peter-ACC 指向的位置。因此,e1 中的调度绑定到全局环境中的名称 peter-acc 和 paul-acc。
  • (f paul-acc)被评估。一个新的环境 e2 由 f 创建。封闭环境是全局的。Paul-ACC在全球可以找到。在 e2 中,banck-account 绑定到 e1 中的调度过程对象,因为那是 paul-acc 指向的地方。因此,关于全球环境的 peter-acc、关于全球环境的 paul-acc 和关于 e2 的银行计数都指向 e1 中的调度过程。
  • 身体被处决。

这一切都正确吗?

让我感到困惑的是,当我在 SICP 练习中遇到这样的事情时,在构建环境图时,我在网上看到人们说"银行账户指的是 paul-acc。Paul-acc指的是peter-acc。为什么在这里使用"引用"一词?关于e2的银行账户实际上指向paul-acc这个名字而不是它的价值吗?

您的第 2 到 5 点是正确的。在你的第1点中,fmake-account没有"指向全球环境的指针——它们本身不需要。它们都是全局环境中的条目、绑定。在这两种情况下,"引用"或"指向"简单值都起作用。

bank-account关于e2实际上指向paul-acc点的值(这与peter-acc点或所指的值相同)。在 Scheme 中,(define n1 n2)表示"在当前环境中设置新的绑定,名为n1,并指向表达式的值n2"。如果n2恰好是一个变量,则其值就是该变量的值。这就是我们谈论 Scheme 的评估语义的原因。

通过查找arg表达式的值,将函数的参数绑定到此,然后在生成的环境中计算函数的主体,(fun arg)计算函数调用:

( (lambda (param) body) arg )
=
(let ( (param arg) )
body)

最新更新