2013-10-27 24 views
5

我在一个大难题是,需要写在ML以下代码:在Python词法范围VS 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函数时定义的函数被创建时创建的环境来调用

任何指针将不胜感激!

谢谢!

回答

6

在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中,只有在另一个函数中定义了一个函数时,才可以创建闭包,而顶层或模块全局名称空间不是函数。但同样的原则适用:在函数定义后,全局变量显然可以改变,所以如果你想在函数定义时“锁定”它的值,你可以使用默认参数。

+0

嗯,你也可以说,在ML中,变量也被引用捕获 - 变量不能分配给ML,所以变量是按值还是按引用捕获都没有区别。 – newacct

+0

是的,我对ML没有足够的了解。 :-) – kindall

6

在ML中 - 至少在ML的功能部分 - 没有变量赋值这样的事情。一旦你声明val x = 1,你不能改变x的值。

可以做什么,但是,是宣布另一个x。当你说val x = 2时,你引入了一个名为x的全新变量,它基本上隐藏了旧变量。但功能f已被定义为指向原始的x,因此它不受影响。

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

+1

ML,期间没有变量赋值。 (甚至没有分配给变量的语法。)可以引用可变数据结构,并且可以修改该数据结构。但是你不能分配给一个变量。 – newacct