【问题标题】:Lexical Scoping and sharing objects词法作用域和共享对象
【发布时间】:2018-04-14 14:21:27
【问题描述】:

考虑 SICP 中的注册帐户过程。

(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)

还有脚注:

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

...

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

..."

在正常情况下,我会在这里有人说:“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 具有指向全局环境的指针。
  • (define peter-acc (make-account 100)) 被评估。 make-account 创建一个新环境 e1。封闭环境是全球性的。内部程序取款、存款和派发被创建并具有指向 e1 的指针。 Dispatch 返回并绑定到全局环境中的名称 peter-acc。
  • (定义 paul-acc peter-acc)进行评估。名称 peter-acc 在全局框架中找到。 paul-acc 绑定到 e1 中的调度过程对象,因为这是 peter-acc 指向的地方。因此,e1 中的 Dispatch 与全局环境中的名称 peter-acc 和 paul-acc 绑定。
  • (f paul-acc) 被评估。一个新的环境 e2 由 f 创建。封闭环境是全球性的。 paul-acc 在全局中找到。在 e2 中,bank-account 绑定到 e1 中的调度过程对象,因为这是 paul-acc 指向的地方。因此,peter-acc 对应全局环境,paul-acc 对应全局环境,bank-acount 对应e2 都指向e1 中的调度过程。
  • 尸体被处决。

这一切都正确吗?

让我困惑的是,当我在 SICP 练习中遇到这样的事情时,在构建环境图时,我看到网上有人说“bank-account 指的是 paul-acc。Paul-acc 指的是 peter-附上。”为什么在这里使用“引用”这个词?与 e2 相关的银行帐户是否实际上指向名称 paul-acc 而不是它的值?

【问题讨论】:

  • “推荐”的措辞是错误的。全局变量paul-acc 绑定到全局变量peter-acc 的值。局部变量 bank-account 绑定到全局变量 paul-acc 的值。
  • 换句话说,@Rainer Joswig。 paul-acc、peter-acc 和bank-account 都绑定到(make-account 100)返回的调度程序?三个人拥有联名银行账户的比喻正确吗?还是三个人拿着一瓶?只是为了确保我完全理解。这也意味着既然“全局变量 paul-acc 绑定到全局变量 peter-acc 的值”,那么全局变量 peter-acc 绑定到全局变量 paul-acc 的值也是正确的对吗?
  • 总是同一个对象。看到函数 eq 了吗? .

标签: reference scheme lisp sicp lexical-scope


【解决方案1】:

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

bank-account 相对于e2 实际上指向paul-acc 指向的(与peter-acc 指向或引用的值相同)。在 Scheme 中,(define n1 n2) 表示“在当前环境中设置新的绑定,命名为 n1,并指向表达式 n2 的值”。如果n2 恰好是一个变量,它的值就是那个变量的值。这就是为什么我们要讨论 Scheme 的 evaluation 语义。

函数调用(fun arg) 是通过找到arg 表达式 来评估的,将函数的参数绑定到这个,然后在结果环境中评估函数的主体:

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

【讨论】:

    猜你喜欢
    • 2021-03-24
    • 2018-10-20
    • 2015-12-04
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    相关资源
    最近更新 更多