自由变量是在函数中使用但未在函数中定义的变量。在你的示例代码,唯一的自由变量是功能change
的变量x
:
let change z = z - x
功能change
使用x
但没有定义它。
作用域的本质是确定一个自由变量指的是什么变量定义,它指的是什么对象是。在您的示例代码中,它归结为确定change
函数中自由变量x
的引用。
对于静态范围,每个自由变量都有一个静态参照物。通过静态地包含代码块直到找到绑定(定义),通过在程序的文本中向外看外部来确定所指对象。在OCaml中,变量绑定是通过函数定义和let
引入的。因此,您正在寻找最接近的change
封闭块,其绑定x
。 x
的最近结合是let proc x =
中的功能参数x
。对于示例呼叫,它具有值2。
对于动态范围界定,指涉是通过嵌套函数查找确定电话是活跃在需要的值的时间。换句话说,您希望在调用链中找到定义名为x
的变量的最内层函数。如果你假装OCaml有动态作用域(它最肯定不),调用链是这样的:
proc => app => change
外面change
调用链功能是app
,它定义一个变量名为x
。因此,对于示例代码,change
的自由变量x
指的是由app
定义的变量x
。在该示例中,它的值为4
。
x
in x + 3
不是一个自由变量。它由proc
定义,并用于proc
。对于示例调用,无论使用哪个范围,它都有值2。
为什么它的价值我认为这不是特别有用的想法用值替换变量。最好把它们看作是绑定到价值观上的。
我也想说(虽然我可能不应该)动态范围是疯了。额外的灵活性绝对不值得额外的复杂性来弄清楚发生了什么。不应该有必要追踪函数调用链来确定变量的绑定。 (在我看来。)
这是一个很好的解释!谢谢一堆! – thestateofmay