Python与ML的词汇范围

时间:2013-10-27 19:58:16

标签: python scope sml ml

我处于一个很大的困境,请使用以下代码编写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 / f>时定义f函数时创建的环境来实现它

任何指针都将非常感谢!

谢谢!

2 个答案:

答案 0 :(得分:7)

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

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

您打算创建一个将x添加到值的函数列表,其中x在0到9之间变化,但是它们都添加9,因为它是{{1的值在循环结束时。

您可以使用默认参数来覆盖它,以便在函数定义时将名称绑定到其值。

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) 这里实际上是一个全局变量。在Python中,只有在另一个函数内定义函数时才能创建闭包,而顶级或模块全局命名空间不是函数。但同样的原则也适用:在定义函数后,显然可以更改全局变量,因此如果要在函数定义时“锁定”其值,则使用默认参数。

答案 1 :(得分:6)

在ML中 - 至少在ML的功能部分 - 没有变量赋值这样的东西。声明val x = 1后,您无法更改x的值。

当你说x时,你会引入一个名为val x = 2的全新变量,它基本上只是隐藏旧的变量。但是函数x已经被定义为指向原始的f,所以它不受影响。

ML确实支持mutable types,它可以像Python中的变量一样重新分配。但他们偏离功能范例,你应该很少有任何理由使用它们。如果你想这样编程,Python就是一个更好的语言。