【问题标题】:Lexical Scope in Python vs MLPython 与 ML 中的词法作用域
【发布时间】:2013-11-06 12:25:13
【问题描述】:

我陷入了两难境地,拿下面用 ML 写的代码:

val x = 1
fun f(y) = x + y
val x = 2
val y = 3
val z = f (x + y)

z 的值为 6。现在,如果我在 python 中编写相同的代码,z 的值为 7。两种语言都声称(实际上教授这些语言的教师声称)具有词法/静态范围。但看起来只有 ML 通过使用在调用 f 时定义 f 函数时创建的环境来拥有它

任何指针将不胜感激!

谢谢!

【问题讨论】:

    标签: python scope sml ml


    【解决方案1】:

    在 Python 中,闭包是按变量而不是按值。所以当你在函数中引用x时,它指的是最近分配给x的值,而不是定义函数时x的值。这会得到非直观的结果,如下所示:

    adders = []
    for x in range(10):
        adders.append(lambda y: x+y)
    

    您打算列出将x 添加到值的函数列表,其中x 的范围为0...9,但它们都添加了9,因为这是x 在末尾的值循环。

    您可以通过使用默认参数将名称绑定到函数定义时的值来覆盖它。

    x = 1
    f = lambda y, x=x: x + y   # x inside f is now locked at 1
    x = 2
    y = 3
    z = f(x + y)
    

    在这个例子中,你甚至没有真正处理闭包:x 这里实际上是一个全局变量。在 Python 中,只有在另一个函数内部定义了一个函数,并且顶级或模块全局命名空间不是函数时,才能创建闭包。但同样的原则也适用:全局变量显然可以在函数定义后改变,所以如果你想在函数定义时“锁定”它的值,你可以使用默认参数。

    【讨论】:

    • 嗯,你也可以说,在机器学习中,变量也是通过引用捕获的——在机器学习中变量不能被赋值,所以变量是按值捕获还是按引用捕获没有区别。跨度>
    • 是的,我对 ML 了解得不够多,无法对此发表任何评论。 :-)
    【解决方案2】:

    在 ML 中——至少在 ML 的功能部分中——没有变量赋值之类的东西。一旦声明了 val x = 1,就不能更改 x 的值。

    然而,您可以做的是声明另一个x。当您说val x = 2 时,您正在引入一个名为x 的全新变量,它基本上只是隐藏了旧变量。但是函数f已经被定义为指向原来的x,所以不受影响。

    ML 确实支持mutable types,它可以像 Python 中的变量一样重新分配。但是它们与功能范式相差甚远,以至于您几乎没有任何理由使用它们。如果你想这样编程,Python 是一种更好的语言。

    【讨论】:

    • ML 中没有变量赋值,句号。 (甚至根本没有分配给变量的语法。)您可以引用可变数据结构,并且可以修改该数据结构。但是你不能分配给一个变量。
    猜你喜欢
    • 2013-11-03
    • 2016-09-23
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    相关资源
    最近更新 更多