Re: [BangPypers] Does Python have lexical scoping?
I'll try to explain a bit, have to admit though, even my understanding is not all that clear, and all is open for further discussion. Noufal Ibrahim KV writes: Okay, I've been struggling through the proglang course on coursera and this thing came up val x = 2; fun f y = x + y; The second line creates a function that adds `x` to it's argument. Since ML is statically scoped, this is really a function that adds 2 to its argument. Even if I later create a new binding for x later like so val x = 10; f (3); I will still get back 5 (i.e. 2 + 3) instead of 13 (10 + 3). This makes sense to me as an example of lexical scoping. The bindings are at the time of definition rather than invocation. Here, technically ML's val bindings are actually immutable. When you actually do a val x = 10; you're creating a new binding for x *shadowing* the previous binding. Something like fun f y = x + y; creates a closure with f, and the free variable x.The closure locks the function with the environment the function was defined in, locking x to 2, as variables are always looked up in the dynamic environment they are defined in before they are called, x is bound to 2. Also ML will not allow you to define a function with x not previously defined, (ie no forward lookups) With python, it's different. The claim is that it has lexical scoping but. x = 2 def f(y): return x + y x = 10 f(3) The answer is, distressingly, 13. The explanation was that although Python has lexical scoping, that closure close over variables rather than values. Here x was a mutable variable, doing a similiar ML construct, ie val x = ref 2 fun f y = !x + 2 f 10 ; evals to 12 x := 10 f 10 ; evals to 20 So this becomes a problem of closures over mutable variables? ie every closure looks up the value of same variable, x which gets mutated around. WDYT? PS I'm not sure whether this mail is going to hit twice in the list, had replied some 30 mins ago, but the mail still failed to appear in the list -- Regards Abhishek ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
On Sun, Nov 9, 2014 at 1:50 PM, Abhishek L abhishek.lekshma...@gmail.com wrote: I'll try to explain a bit, have to admit though, even my understanding is not all that clear, and all is open for further discussion. Noufal Ibrahim KV writes: Okay, I've been struggling through the proglang course on coursera and this thing came up val x = 2; fun f y = x + y; The second line creates a function that adds `x` to it's argument. Since ML is statically scoped, this is really a function that adds 2 to its argument. Even if I later create a new binding for x later like so val x = 10; f (3); I will still get back 5 (i.e. 2 + 3) instead of 13 (10 + 3). This makes sense to me as an example of lexical scoping. The bindings are at the time of definition rather than invocation. Here, technically ML's val bindings are actually immutable. When you actually do a val x = 10; you're creating a new binding for x *shadowing* the previous binding. Something like fun f y = x + y; creates a closure with f, and the free variable x.The closure locks the function with the environment the function was defined in, locking x to 2, as variables are always looked up in the dynamic environment they are defined in before they are called, x is bound to 2. Also ML will not allow you to define a function with x not previously defined, (ie no forward lookups) With python, it's different. The claim is that it has lexical scoping but. x = 2 def f(y): return x + y x = 10 f(3) The answer is, distressingly, 13. The explanation was that although Python has lexical scoping, that closure close over variables rather than values. Here x was a mutable variable, doing a similiar ML construct, ie val x = ref 2 fun f y = !x + 2 f 10 ; evals to 12 x := 10 f 10 ; evals to 20 So this becomes a problem of closures over mutable variables? ie every closure looks up the value of same variable, x which gets mutated around. WDYT? PS I'm not sure whether this mail is going to hit twice in the list, had replied some 30 mins ago, but the mail still failed to appear in the list Unless attachments are present, it should reach in time . -- Regards Abhishek ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers -- *Thanks RegardskracekumarTalk is cheap, show me the code -- Linus Torvaldshttp://kracekumar.com http://kracekumar.com* ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
On Sun, Nov 09 2014, Abhishek L wrote: [...] Here x was a mutable variable, doing a similiar ML construct, ie val x = ref 2 fun f y = !x + 2 f 10 ; evals to 12 x := 10 f 10 ; evals to 20 So this becomes a problem of closures over mutable variables? ie every closure looks up the value of same variable, x which gets mutated around. WDYT? [...] So the explanation I got is that it binds the environment at definition time but the environment means a mutable table of key value pairs. In other words, the closure closes only over the name of the variable and not the value at definition time. I don't really understand how useful this is unless you have some kind of environment that you can't get to (e.g. non local inside a function etc.). Also, and this is my real question, How is lexical scoping with a mutable environment different from dynamic scoping? -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping? (Noufal Ibrahim KV)
Ref: This mail thread: https://mail.python.org/pipermail/bangpypers/2014-November/010549.html Date: Sun, 09 Nov 2014 14:44:26 +0530 From: Noufal Ibrahim KV nou...@nibrahim.net.in Subject: Re: [BangPypers] Does Python have lexical scoping? Message-ID: 87y4rkpwgd@nibrahim.net.in [ ... snip ...] How is lexical scoping with a mutable environment different from dynamic scoping? Here's my 0.0002 BTC; trying to reason from first principles: Context: In SML (and perhaps all strongly functional PLs), all values are immutable by default. Re-stating facts: Now, any function in SML is just a value (that can be passed around). This value is, semantically, a closure that consists of (A) the function definition and (B) the environment that was current at the time it was defined. This closure, though somewhat special--semantically a pair of (A) and (B)--is really designed to be just a value. Intuition: If the PL is to guarantee the immutability of this function closure, then _both_ (A) and (B) must be guaranteed immutable as well. Re: Python semantics: I'm not terribly familiar with Python semantics. But I think if values/variables are mutable by default, then the function closure's contract differs from to SML exactly the way Noufal describes it... i.e. the closure _cannot_ close over values, it can only close over variables defined within the lexical scope of a function. Contrast with a mutable SML variant: I think if I defined 'x' as a mutable ref in SML and reassigned some other value to it (set-bang), I can violate the function closure contract. Re: Dynamic scope: AFAIK, this goes one step beyond (behind?) mutable variables. Even if *we* don't mutate the value of symbol 'x', another process is free to inject some identically named symbol 'x' into our current environment, just in time to mess with the wiring of an otherwise sane function. Hopefully I'm making sense. - Aditya https://twitter.com/adityaathalye ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
On Sun, Nov 9, 2014 at 1:14 AM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: How is lexical scoping with a mutable environment different from dynamic scoping? I think you should post this in python-dev and you might get answers with rigorous definitions. Here is my short snippet which shows a behavior which does not indicate a dynamic binding nature. # example.py x = 10 y = lambda: x def f(): x = 20 # This is not rebinding. It is creating a new local variable by name x # But we are referring to x in y function call, so for the definition of dynamic binding (?) # should y() see x defined in the local scope instead of the previously assigned value. print(y()) return y() x = 30 # This is rebinding in the same scope. print(f()) $ python example.py 30 30 ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
Senthil Kumaran writes: On Sun, Nov 9, 2014 at 1:14 AM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: How is lexical scoping with a mutable environment different from dynamic scoping? I think you should post this in python-dev and you might get answers with rigorous definitions. Here is my short snippet which shows a behavior which does not indicate a dynamic binding nature. # example.py x = 10 y = lambda: x def f(): x = 20 # This is not rebinding. It is creating a new local variable by name x # But we are referring to x in y function call, so for the definition of dynamic binding (?) # should y() see x defined in the local scope instead of the previously assigned value. print(y()) return y() x = 30 # This is rebinding in the same scope. print(f()) $ python example.py 30 30 Just for understanding, trying the same snippet in emacs lisp which has dynamic binding will reveal the value of `x' as 20, as expected in dynamic binding as we change the value of x inside the function. (setq x 10) (defun y () x) (defun f () (setq x 20) (print (y)) (y)) (print (f)) ; 20 20 -- Abhishek ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
On Sun, Nov 9, 2014 at 10:38 AM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: Okay, I've been struggling through the proglang course on coursera and this thing came up val x = 2; fun f y = x + y; The second line creates a function that adds `x` to it's argument. Since ML is statically scoped, this is really a function that adds 2 to its argument. Even if I later create a new binding for x later like so val x = 10; f (3); I will still get back 5 (i.e. 2 + 3) instead of 13 (10 + 3). This makes sense to me as an example of lexical scoping. The bindings are at the time of definition rather than invocation. With python, it's different. The claim is that it has lexical scoping but. x = 2 def f(y): return x + y x = 10 f(3) The answer is, distressingly, 13. The explanation was that although Python has lexical scoping, that closure close over variables rather than values. Meaning that the variables (and not their values) at definition time are stored in the closure. This is how elisp does it which claims to be, by default, dynamically scoped. (setq m 5) (defun test (x) (+ x m)) (test 3) ; - 8 (setq m 15) (test 3) ; - 18 So, my question is, how different is this from dynamic scoping (like in elisp) where the values are actually picked up from the execution (rather than definition) environment. This business of closes over variables rather than values sounds like a cop out. Comments? There are cases where both lexical scope and dynamic scope produce same results. The example that you gave falls into that category. Try the following example: (setq x 5) (defun getx () x) (getx) (defun f (x) (getx)) (f 10) (setq x 4) (f 10) The function getx takes the values of x that is closest to in the stack, not the one that is lexically closest. Another example to demonstrate that. (defun g (x) (h x)) (defun h (y) (getx)) (g 3) With lexical scoping a can be resolved at the time of declaring the function it self (as in name x in getx is alias to x defined in the top-level), where as with dynamic scoping it can only be determined at the run time. Because of this lexical scoping is usually faster. Anand ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
Re: [BangPypers] Does Python have lexical scoping?
On Mon, Nov 10, 2014 at 12:17 PM, Anand Chitipothu anandol...@gmail.com wrote: On Sun, Nov 9, 2014 at 10:38 AM, Noufal Ibrahim KV nou...@nibrahim.net.in wrote: Okay, I've been struggling through the proglang course on coursera and this thing came up val x = 2; fun f y = x + y; The second line creates a function that adds `x` to it's argument. Since ML is statically scoped, this is really a function that adds 2 to its argument. Even if I later create a new binding for x later like so val x = 10; f (3); I will still get back 5 (i.e. 2 + 3) instead of 13 (10 + 3). This makes sense to me as an example of lexical scoping. The bindings are at the time of definition rather than invocation. With python, it's different. The claim is that it has lexical scoping but. x = 2 def f(y): return x + y x = 10 f(3) The answer is, distressingly, 13. The explanation was that although Python has lexical scoping, that closure close over variables rather than values. Meaning that the variables (and not their values) at definition time are stored in the closure. This is how elisp does it which claims to be, by default, dynamically scoped. (setq m 5) (defun test (x) (+ x m)) (test 3) ; - 8 (setq m 15) (test 3) ; - 18 So, my question is, how different is this from dynamic scoping (like in elisp) where the values are actually picked up from the execution (rather than definition) environment. This business of closes over variables rather than values sounds like a cop out. Comments? There are cases where both lexical scope and dynamic scope produce same results. The example that you gave falls into that category. Sorry, forgot to add the output. Try the following example: (setq x 5) (defun getx () x) (getx) (defun f (x) (getx)) (f 10) prints 10, the x from function f, not global x. (setq x 4) (f 10) prints 10 again. changing the global x don't have any affect. Python or scheme (lexical scoping) would produce 4 in this case. The function getx takes the values of x that is closest to in the stack, not the one that is lexically closest. Another example to demonstrate that. (defun g (x) (h x)) (defun h (y) (getx)) (g 3) prints 3. Picks x from 2 stack frames below. With lexical scoping a can be resolved at the time of declaring the function it self (as in name x in getx is alias to x defined in the top-level), where as with dynamic scoping it can only be determined at the run time. Because of this lexical scoping is usually faster. Anand ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers
[BangPypers] Does Python have lexical scoping?
Okay, I've been struggling through the proglang course on coursera and this thing came up val x = 2; fun f y = x + y; The second line creates a function that adds `x` to it's argument. Since ML is statically scoped, this is really a function that adds 2 to its argument. Even if I later create a new binding for x later like so val x = 10; f (3); I will still get back 5 (i.e. 2 + 3) instead of 13 (10 + 3). This makes sense to me as an example of lexical scoping. The bindings are at the time of definition rather than invocation. With python, it's different. The claim is that it has lexical scoping but. x = 2 def f(y): return x + y x = 10 f(3) The answer is, distressingly, 13. The explanation was that although Python has lexical scoping, that closure close over variables rather than values. Meaning that the variables (and not their values) at definition time are stored in the closure. This is how elisp does it which claims to be, by default, dynamically scoped. (setq m 5) (defun test (x) (+ x m)) (test 3) ; - 8 (setq m 15) (test 3) ; - 18 So, my question is, how different is this from dynamic scoping (like in elisp) where the values are actually picked up from the execution (rather than definition) environment. This business of closes over variables rather than values sounds like a cop out. Comments? -- Cordially, Noufal http://nibrahim.net.in ___ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers