Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lexical Scope in Python vs ML

Tags:

python

scope

sml

ml

I'm in a big dilemma, take the following code written in ML:

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

The value of z is 6. Now if I write the same code in python the value of z would be 7. And both languages claim(actual the teachers that teach these languages claim this) to have Lexical / Static scope. But it looks like only ML has it by using the environment that was creating when the f function was defined whenever f is called

Any pointers would be greatly appreciated!

Thanks!

like image 674
Mihai Vinaga Avatar asked Oct 27 '13 19:10

Mihai Vinaga


People also ask

Does Python have lexical scope?

I'll use that. JavaScript and other languages such as the C family and Python use lexical scope , also called static scope , which means that scope nests according to where functions and variables are declared.

Is lexical scope and closure same?

The lexical scope allows a function scope to access statically the variables from the outer scopes. Finally, a closure is a function that captures variables from its lexical scope. In simple words, the closure remembers the variables from the place where it is defined, no matter where it is executed.

What is a lexical scope?

Lexical scoping, also known as static scoping, is a convention used with many modern programming languages. It refers to setting the scope, or range of functionality, of a variable so that it may be called (referenced) from within the block of code in which it is defined.

Does Python use dynamic scoping?

Python uses lexical scoping, there is no dynamic scoping.


2 Answers

In Python, closures are by variable, not by value. So when you refer to x in a function, it refers to the most recent value assigned to x, not to the value of x when the function was defined. This gets non-intuitive results like the one below:

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

You intend to make a list of functions that add x to a value, where x varies from 0...9, but instead they all add 9 because that's the value of x at the end of the loop.

You can override this by using a default argument to bind the name to its value at the time of the function definition.

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)

In this example you're not even actually dealing with a closure: x here is actually a global variable. In Python, a closure can be created only when a function is defined inside another function, and the top-level or module-global namespace is not a function. But the same principle applies: the global variable can obviously be changed after the function is defined, so if you want to "lock in" its value at the time of function definition, you use a default argument.

like image 193
kindall Avatar answered Oct 15 '22 03:10

kindall


In ML - at least, in the functional part of ML - there is no such thing as variable assignment. Once you have declared that val x = 1, you can't change the value of that x.

What you can do, however, is declare another x. When you say val x = 2, you're introducing a brand new variable called x, which basically just hides the old one. But the function f has already been defined to point to the original x, so it's not affected.

ML does support mutable types, which can be reassigned just like variables in Python. But they stray so far from the functional paradigm that you should rarely have any reason to use them. If you want to program like that, Python's a far better language for it.

like image 42
Nick Barnes Avatar answered Oct 15 '22 03:10

Nick Barnes