【问题标题】:Dynamic Scoping - Deep Binding vs Shallow Binding动态范围 - 深层绑定与浅层绑定
【发布时间】:2009-11-18 02:12:18
【问题描述】:

我一直试图理解浅绑定和深绑定,维基百科没有很好地解释它。假设我有以下代码,如果语言使用动态范围,输出会是什么

a) 深度绑定

b) 浅绑定?

x: integer := 1
y: integer := 2

procedure add
  x := x + y

procedure second(P:procedure)
  x:integer := 2
  P()

procedure first
  y:integer := 3
  second(add)

----main starts here---
first()
write_integer(x)

【问题讨论】:

  • 这是 Python 吗?您的问题与语言无关吗?请说明

标签: language-agnostic binding scoping dynamic-scope


【解决方案1】:

深度绑定在过程作为参数传递时绑定环境

浅绑定在实际调用过程时绑定环境

因此,当 add 被传递到第二个时,具有深度绑定的动态范围 环境是 x = 1, y = 3,x 是全局 x,所以它将 4 写入全局 x,这是由 write_integer 拾取的。

浅绑定只会向上遍历,直到找到与名称对应的最近变量,因此答案将为 1。

【讨论】:

  • 对于浅绑定,如果我将 "write_integer(y)" 放在第二个过程中(在 P() 之前),我会得到 3 还是 2 ?同样对于浅绑定,我可以不更改全局变量的值吗?
  • 具有浅绑定的动态范围将打印“5”。这是因为动态作用域使用调用它的方法中的绑定(变量值组合)。因此,具有浅绑定的动态范围将使用绑定x = 2,这与具有深度绑定的动态范围不同,后者将使用(如@jjia6395 所说)x = 1(从add 开始的绑定被传递到方法second作为参数)。
  • @AntoineDahan not if second 动态地为一个名为 x 的新变量引入了新绑定(通过使用 x:integer := 2 而不是 x := 2 很明显),所以add(从second 调用,而second 还活着)将动态创建的x 更改为5。但write_integer(x) 引用了全局x。因此,此伪代码具有误导性。它应该在定义中使用“=”,例如x:integer = 1,并在变异分配中使用“:=”,例如x := x + y
  • 也就是说,我反对这种对术语的滥用——在 LISP 上下文中,它们首次出现的地方,“深”和“浅”只是动态的实现技术词法作用域,并且可用于实现both,因此如果正确实现,则与程序内部没有区别。这里所谓的“深度”绑定只是一种误解——它应该是在谈论“免费的 var 解析时间”,并通过写 second( closed(add,(x,y)) ) 来使其显式。在这两种情况下,它仍然是动态名称解析。你只想要2个freeze'em。所以冻结他们。明确!
【解决方案2】:

a) 在深度绑定中,我们处理 add 的环境,其中 x 指的是全局 x,y 指的是局部于 first 的 y(最后执行的具有 y 声明的函数)

x(全局)= x(全局)+ y(局部):x = 1 + 3 = 4

b) 在浅绑定中,我们处理的是 second 的环境,其中 x 指的是局部于 second 的 x,y 指的是局部于 first 的 y(最后执行的函数,其声明为 y)

x(本地)= x(本地)+ y(本地):x = 2 + 3 = 5

但是:write_integer(x) 输出全局 x 等于 1

终于

a) 4

b) 1

【讨论】:

    【解决方案3】:

    【讨论】:

    • 不,使用浅绑定它输出1,正如 jjia6395 所说。这是因为对P() 的调用修改了second 的本地x,然后在second 返回时消失。对write_integer(x) 的调用会打印出未修改的全局x
    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 2017-02-22
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多