Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
[Fredrik Lundh] def counter(num): num = mutable_int(num) def inc(): num += 1 return num return inc feel free to replace that += with an .add(1) method call; the point wasn't the behaviour of augmented assigment, the point was that that the most common use pattern involves *mutation* of the target object. the syntax isn't that important, really. No it isn't, but I believe it deserves notice that it's easy enough, currently, to mock your mutable_int replacing the += by a simple +, while the += itself is not possible even though it reflects the intention more precisely. [Jeremy Hylton] Mutation is different from rebinding.A tuple is immutable, but you can rebind the variable that refers to the tuple. It's more than just rebinding, it's rebinding to a function of the currently bound value. And /that/ has clear features in common with mutation (witness most of the current semantics and implementation of augmented assignments, ie, how much and far it manages to postpone the decision as to which is actually the case). I think we will confuse users if we use the term mutation to refer to name binding. Name binding is already a subtle issue, so I think the risk is significant. I'd tend to agree, but imho there is a complementary risk of propagating confusion by denying what augmented assignments clearly show : that rebinding to a function of the currently bound value has so much in common with mutation that augmented assignments allow to confuse both cases in source code. Except for the scoping issue under discussion, that is. Cheers, BB -- C++ is a contradiction in terms - Lorentz, Einstein, Poincaré ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/12/06, Fredrik Lundh [EMAIL PROTECTED] wrote: Boris Borcic wrote: note that most examples of this type already work, if the target type is mutable, and implement the right operations: def counter(num): num = mutable_int(num) def inc(): num += 1 return num return inc I agree with you (and argued it in scopes vs augmented assignment vs sets recently) that mutating would be sufficient /if/ the compiler would view augmented assignment as mutations operators feel free to replace that += with an .add(1) method call; the point wasn't the behaviour of augmented assigment, the point was that that the most common use pattern involves *mutation* of the target object. the syntax isn't that important, really. Mutation is different from rebinding. A tuple is immutable, but you can rebind the variable that refers to the tuple. I think we will confuse users if we use the term mutation to refer to name binding. Name binding is already a subtle issue, so I think the risk is significant. Jeremy ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Terry Reedy wrote: Boris Borcic [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] I agree with you (and argued it in scopes vs augmented assignment vs sets recently) that mutating would be sufficient /if/ the compiler would view augmented assignment as mutations operators : Mutation is an operation on objects. Binding is an operation on namespaces. The difference between objects and namespaces (and the actions thereupon) is fundamental to Python. If you want to put it that way, but I think it muddies the relevant water to confuse scopes with namespaces, or compiler with interpreter responsibilities. Deciding whether an augmented assignment results in a bona-fide mutation or in the rebinding of an already bound name in an unchanging namespace : that's the responsibility of the interpreter. [Well, nowa-pypy-days I guess we should say, not even of the interpreter, but of the object space]. Deciding how names bind to lexical scopes, that's the responsibility of the compiler. When faced with such code as below [ while mutable_int() might as well equal (lambda x : x) as far as the compiler is concerned ] def counter(num): num = mutable_int(num) def inc(): num += 1 return num return inc It is disingenuous that the /scope-binding phase/ of the compiler design feigns to believe that my num += 1 is really more like num = 2 than it is like a mutation operator, given that : whether the statement ultimately results in REbinding or mutation is /irrelevant/ to the fact that any augmented assignment requires an autonomous initial binding of the variable to ever function. - what is exactly the sort of assertions independent of run-time details that compilers are made to reason about. Asking the interpreter to view one thing as something else which it isn't can only lead to more confusion. I think its impossible to be more confused than setting things up so that the programmer of counter() above gets : UnboundLocalError: local variable 'num' referenced before assignment When what is really meant is (your drift no ?) : We think allowing you what you want would make a=b=c ; a += d ; b = b+d ; assert a == b more difficult for newbies to understand and predict in context In particular, asking that arithmetic operations on immutable numbers be seen as mutations seems wacky to me. Nobody really asked for this (I invite you to check), but even so I feel an exact analysis of the impact on use-cases would be worth its while. which it doesn't as far as concerns scopes where a variable appears as target only of /augmented/ assignments. The interpreter/compiler, as far as I can think, never views binding as mutation, nor should it. The request that it do so The request is not for the compiler/interpreter to view binding as mutation, it is for the /compiler/ to view /REbinding/ just like mutation - which it is as far as compiler responsibilities are concerned imo. makes me wonder whether it might have been a mistake to allow mutable objects in an augmented assignment to choose to implement the associated operation as an in-place mutation. I agree with you that removing this possibility would provide better consistency to your position. Best regards, Boris Borcic -- C++ is a contradiction in terms - Lorentz, Einstein, Poincaré ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Boris Borcic wrote: note that most examples of this type already work, if the target type is mutable, and implement the right operations: def counter(num): num = mutable_int(num) def inc(): num += 1 return num return inc I agree with you (and argued it in scopes vs augmented assignment vs sets recently) that mutating would be sufficient /if/ the compiler would view augmented assignment as mutations operators feel free to replace that += with an .add(1) method call; the point wasn't the behaviour of augmented assigment, the point was that that the most common use pattern involves *mutation* of the target object. the syntax isn't that important, really. /F ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Ka-Ping Yee wrote: On Mon, 10 Jul 2006 [EMAIL PROTECTED] wrote: I think Talin's got a point though. It seems hard to find one short English word that captures the essence of the desired behavior. None of the words in his list seem strongly suggestive of the meaning to me. I suspect that means one's ultimately as good (or as bad) as the rest. What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). Well, I just think that a fix for an aesthetic wart should be, well, aesthetic :) I also think that it won't be a complete disaster if we do nothing at all - there *are* existing ways to deal with this problem; there are even some which aren't hackish and non-obvious. For example, its easy enough to create an object which acts as an artificial scope: def x(): scope = object() scope.x = 1 def y(): scope.x = 2 To my mind, the above code looks about as elegant and efficient as most of the proposals put forward so far, and it already works. How much are we really saving here by building this feature into the language? -- Talin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Jeremy Hylton wrote: To express this email in the positive form: 1. Reserved words should be real words. 2. The meaning of the word should be clear. 3. Put statements in positive form. (Strunk White) 4. The word should sound good. agreed. a word should describe what a thing is, not what it isn't. not entirely sure about global, though; things like outer and extern(al) might be better (especially if we could ignore C, which I don't think we can). cannot think of prior art here, but there has to be some. anyone ? /F ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Talin wrote: I also think that it won't be a complete disaster if we do nothing at all - there *are* existing ways to deal with this problem; there are even some which aren't hackish and non-obvious. For example, its easy enough to create an object which acts as an artificial scope: def x(): scope = object() scope.x = 1 def y(): scope.x = 2 To my mind, the above code looks about as elegant and efficient as most of the proposals put forward so far, and it already works. How much are we really saving here by building this feature into the language? I don't think anyone commented on my mutable post, but as I mentioned in that post, if you look at the use cases for this, what most use cases really need is *mutation*, not *rebinding*. /F ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Talin wrote: Ka-Ping Yee wrote: On Mon, 10 Jul 2006 [EMAIL PROTECTED] wrote: I think Talin's got a point though. It seems hard to find one short English word that captures the essence of the desired behavior. None of the words in his list seem strongly suggestive of the meaning to me. I suspect that means one's ultimately as good (or as bad) as the rest. What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). Well, I just think that a fix for an aesthetic wart should be, well, aesthetic :) I also think that it won't be a complete disaster if we do nothing at all - there *are* existing ways to deal with this problem; there are even some which aren't hackish and non-obvious. For example, its easy enough to create an object which acts as an artificial scope: def x(): scope = object() scope.x = 1 def y(): scope.x = 2 To my mind, the above code looks about as elegant and efficient as most of the proposals put forward so far, and it already works. How much are we really saving here by building this feature into the language? def x(): ...:scope = object() ...:scope.x = 1 ...:def y(): ...:scope.x = 2 x() --- exceptions.AttributeErrorTraceback (most recent call last)ipython console I've often found it a nuisance that you can't instantiate an 'object', to use as a mutable 'namespace', but instead have to define an arbitrary empty class. What happened to the 'namespace' proposal ? Michael Foord http://www.voidspace.org.uk/python/index.shtml -- Talin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Fuzzyman wrote: I've often found it a nuisance that you can't instantiate an 'object', to use as a mutable 'namespace', but instead have to define an arbitrary empty class. What happened to the 'namespace' proposal ? The code and the pre-PEP [1] are still out there, but Carlos, Steve and I all got distracted by other things. It really needs to go back to c.l.p to thrash out some of the name collision prblems (e.g. should *all* access to methods, even special methods, be via type(x)?). Cheers, Nick. [1] http://namespace.python-hosting.com/wiki/NamespacePep -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://www.boredomandlaziness.org ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
outbound x = 1 x = 2 evaluating using Jeremy Hilton's' list: 1. is a real word 2. For me - in python - it would mean: Is found in 'outer' scope and is already bound. And the literal meaning of 'outbound 'headed away' [1] is pretty darn close to what I mean when I spell the usual mutables kluge. 3 statement is positive form 4. I like it could not find a use of outbound in python source (2.4.3) [1] http://dictionary.reference.com/search?q=outbound Robin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Robin Bryce wrote: outbound x = 1 FWINW, to me 'nonlocal' clearly and immediately tells you what you need to know about the variable. 'outbound' has no programming associations for me (it makes me think of 'outward bound' and roaming the great outdoors). So negative or not I'm +1 on nonlocal if we really need this... (Hey, and I'm a native.) Michael Foord http://www.voidspace.org.uk/python/index.shtml x = 2 evaluating using Jeremy Hilton's' list: 1. is a real word 2. For me - in python - it would mean: Is found in 'outer' scope and is already bound. And the literal meaning of 'outbound 'headed away' [1] is pretty darn close to what I mean when I spell the usual mutables kluge. 3 statement is positive form 4. I like it could not find a use of outbound in python source (2.4.3) [1] http://dictionary.reference.com/search?q=outbound Robin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Matthew Barnes wrote: its meaning in C/C++ (i.e. the symbol is defined outside of the current scope). It means more than that -- it means defined outside the current *file*. That's much too drastic for what we want. -- Greg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Mon, 10 Jul 2006 [EMAIL PROTECTED] wrote: I think Talin's got a point though. It seems hard to find one short English word that captures the essence of the desired behavior. None of the words in his list seem strongly suggestive of the meaning to me. I suspect that means one's ultimately as good (or as bad) as the rest. What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/10/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: On Mon, 10 Jul 2006 [EMAIL PROTECTED] wrote: I think Talin's got a point though. It seems hard to find one short English word that captures the essence of the desired behavior. None of the words in his list seem strongly suggestive of the meaning to me. I suspect that means one's ultimately as good (or as bad) as the rest. What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). It's a made-up word. You won't find it in the dictionary and the google define: query sends me to a wikipedia page about quantum mechanics. It also expresses itself in the negative form not local as opposed to the positive form like global this is a global. Finally, I think it sounds yucky. To express this email in the positive form: 1. Reserved words should be real words. 2. The meaning of the word should be clear. 3. Put statements in positive form. (Strunk White) 4. The word should sound good. global meets all of these requirements. free was the word I remember preferring from earlier discussions, but I think it fails #2. (Too much confusion about freeing memory, for example.) Jeremy -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/jeremy%40alum.mit.edu ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). It sounds a bit awkward to me. Also, it would be nice if the keyword indicated which scope was operative. If I've followed the discussions correctly, I think the parent scope would be operative, so I humbly suggest parent. Mike ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/10/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). On Mon, 10 Jul 2006, Jeremy Hylton wrote: It's a made-up word. You won't find it in the dictionary and the google define: query sends me to a wikipedia page about quantum mechanics. Two million Google hits for nonlocal seems like plenty. The explanation of nonlocal is pretty straightforward -- If the definition of f() contains an assignment to x, then x is a local variable in f, unless x is declared nonlocal. To express this email in the positive form: 1. Reserved words should be real words. 2. The meaning of the word should be clear. 3. Put statements in positive form. (Strunk White) 4. The word should sound good. global meets all of these requirements. But it's the wrong word. Purple also meets all of these requirements. I'd rather accurately express the concept in the negative (the true meaning really is in the negative: don't make a new binding), than choose a simple-sounding word that is essentially a lie. x = 1 def f(x): print x def g(): global x x = 3 print x The x used in g is not global at all -- it belongs to f. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/10/06, Jeremy Hylton [EMAIL PROTECTED] wrote: On 7/10/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: On Mon, 10 Jul 2006 [EMAIL PROTECTED] wrote: I think Talin's got a point though.It seems hard to find one short English word that captures the essence of the desired behavior.None of the words in his list seem strongly suggestive of the meaning to me.I suspect that means one's ultimately as good (or as bad) as the rest. What's wrong with nonlocal?I don't think i've seen an argument against that one so far (from Talin or others).It's a made-up word.You won't find it in the dictionary and the google define: query sends me to a wikipedia page about quantummechanics.It also expresses itself in the negative form not localas opposed to the positive form like global this is a global. Finally, I think it sounds yucky.To express this email in the positive form:1. Reserved words should be real words.2. The meaning of the word should be clear.3. Put statements in positive form.(Strunk White) 4. The word should sound good.global meets all of these requirements.free was the word Iremember preferring from earlier discussions, but I think it fails #2. (Too much confusion about freeing memory, for example.) I remember previous discussions also referring to spelling this as outer which IMO passes #2 as well as the other, although arguably #4 is subjective ;-).-Almann -- Almann T. Goo[EMAIL PROTECTED] ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum wrote: Then let's allow nonlocal x = 12 as a shortcut for nonlocal x x = 12 I thought you didn't like that, because in nonlocal x = 12 x = 42 it's not clear whether these are talking about the same x or not. -- Greg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/10/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: On 7/10/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: What's wrong with nonlocal? I don't think i've seen an argument against that one so far (from Talin or others). On Mon, 10 Jul 2006, Jeremy Hylton wrote: It's a made-up word. You won't find it in the dictionary and the google define: query sends me to a wikipedia page about quantum mechanics. Two million Google hits for nonlocal seems like plenty. The explanation of nonlocal is pretty straightforward -- If the definition of f() contains an assignment to x, then x is a local variable in f, unless x is declared nonlocal. To express this email in the positive form: 1. Reserved words should be real words. 2. The meaning of the word should be clear. 3. Put statements in positive form. (Strunk White) 4. The word should sound good. global meets all of these requirements. But it's the wrong word. Purple also meets all of these requirements. No. Don't be silly. The current use of global meets the requirements. The meaning there is clear, because global means global namespace. If purple were a keyword, I wouldn't know what it means. I was not proposing the use of global for some other meaning (and thought I made that clear in the remainder of the message). Jeremy I'd rather accurately express the concept in the negative (the true meaning really is in the negative: don't make a new binding), than choose a simple-sounding word that is essentially a lie. x = 1 def f(x): print x def g(): global x x = 3 print x The x used in g is not global at all -- it belongs to f. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Mon, 2006-07-10 at 16:43 -0400, Jeremy Hylton wrote: To express this email in the positive form: 1. Reserved words should be real words. 2. The meaning of the word should be clear. 3. Put statements in positive form. (Strunk White) 4. The word should sound good. As I've been following this thread I find that the word extern keeps coming to mind. It's debatable whether extern passes #1, although my dictionary has an entry for it. But more importantly, there seems to be fairly strong parallels between what we're discussing here and its meaning in C/C++ (i.e. the symbol is defined outside of the current scope). So I think extern easily passes #2 for C/C++ programmers, and I think others can probably guess that extern == external (my wife did, at least). I haven't seen this suggested yet so I thought I'd just throw it out there. Matt ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/10/06, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I don't think the keyword should indicate a scope. I'd prefer it if LOAD_WHATEVER just percolated its way up the chain of cells (or could be identified at compile time by inspecting the AST as I think Guido intends) without the programmer having to name the binding scope. I agree completely. I realize that probably wasn't clear when I said it would be nice if the keyword indicated which scope was operative. I was really only trying to proffer a keyword which would hopefully suggest to a newbie that they should percolate up the chain of scopes. In this sense, the word outer works for me, but I'm sympathetic to Andrew Koenig's argument that outer is confusing because the innermost binding is actually affected. Since it might not just be in the immediate parent scope, how about ancestor? 0.5 wink That thought had occurred to me, but then I beat it down with a stick :-) My rationale was that the affected binding is the one seen by the parent, even if the parent did not create the binding itself. Greg Ewing's point about parent being a common variable name is well-taken, though. Mike ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Sun, 9 Jul 2006, Andrew Koenig wrote: Sounds reasonable to me. If we're talking py3k I'd chuck global as a keyword though and replace it with something like outer. I must say that I don't like outer any more than I like global. The problem is that in both cases we are selecting the *inner*most definition that isn't in the current scope. That's why nonlocal is a better choice in my opinion. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Ka-Ping Yee wrote: On Sun, 9 Jul 2006, Andrew Koenig wrote: Sounds reasonable to me. If we're talking py3k I'd chuck global as a keyword though and replace it with something like outer. I must say that I don't like outer any more than I like global. The problem is that in both cases we are selecting the *inner*most definition that isn't in the current scope. That's why nonlocal is a better choice in my opinion. Some alternatives: use x using x with x -- recycle a keyword? reuse x use extant x share x common x same x borrow x existing x Although, to be perfectly honest, the longer this discussion goes on, the more that I find that I'm not buying Guido's argument about it being better to define this at the point of use rather than at the point of definition. I agree with him that point of use is more Pythonic, but I'm also beginning to believe that there are some good reasons why many other languages do it the other way. Part of the reason why its so hard to name this feature is that it's real name is something like Hey, Python, you know that cool funky thing you do with defining variables in the same scope as they are assigned? Well, don't do that here. -- Talin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Talin wrote: Some alternatives: use x using x with x -- recycle a keyword? reuse x use extant x share x common x same x borrow x existing x Although, to be perfectly honest, the longer this discussion goes on, the more that I find that I'm not buying Guido's argument about it being better to define this at the point of use rather than at the point of definition. I agree with him that point of use is more Pythonic, but I'm also beginning to believe that there are some good reasons why many other languages do it the other way. Part of the reason why its so hard to name this feature is that it's real name is something like Hey, Python, you know that cool funky thing you do with defining variables in the same scope as they are assigned? Well, don't do that here. (Followup to my own comment) There are really 3 places where you can indicate that a variable is to be reused instead of redefined: 1) The point of definition in the outer scope, 2) A declaration in the inner scope, and 3) The actual point of assignment. #1 is what I've been pushing for, #2 is what most of the discussion has been about, #3 has been talked about a little bit in the context of an augmented assignment operator. I actually like #3 a little better than #2, but not with a new operator. I'm thinking more along the lines of a keyword that modifies and assignment statement: rebind x = 10 Other possible keywords are: modify, mutate, change, update, change, etc... My gut feeling is that most code that wants to use this feature only wants to use it in a few places. A good example is fcgi.py (implements WSGI for FastCGI), where they use a mutable array to store a flag indicating whether or not the headers have already been sent. -- Talin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/9/06, Talin [EMAIL PROTECTED] wrote: Talin wrote: Some alternatives: use x using x with x -- recycle a keyword? reuse x use extant x share x common x same x borrow x existing x Of these, I like reuse, share, common slightly better than the rest. Although, to be perfectly honest, the longer this discussion goes on, the more that I find that I'm not buying Guido's argument about it being better to define this at the point of use rather than at the point of definition. I agree with him that point of use is more Pythonic, but I'm also beginning to believe that there are some good reasons why many other languages do it the other way. Well, I still don't like point of definition. It means that something far away can change the interpretation of something local. The reason other languages do it differently is that variable declarations are obligatory. It's really unacceptable that when I see def foo(): x = 12 I would have to search the entire module for a possible definition of a global named 'x' to see whether the x assigned to here is local or not. Part of the reason why its so hard to name this feature is that it's real name is something like Hey, Python, you know that cool funky thing you do with defining variables in the same scope as they are assigned? Well, don't do that here. Sorry, that sounds like a B.S. argument. You can translate most language constructs into long sentences if you want to. (Followup to my own comment) There are really 3 places where you can indicate that a variable is to be reused instead of redefined: 1) The point of definition in the outer scope, 2) A declaration in the inner scope, and 3) The actual point of assignment. #1 is what I've been pushing for, #2 is what most of the discussion has been about, #3 has been talked about a little bit in the context of an augmented assignment operator. I actually like #3 a little better than #2, but not with a new operator. I'm thinking more along the lines of a keyword that modifies and assignment statement: rebind x = 10 Other possible keywords are: modify, mutate, change, update, change, etc... A problem with this is the ambiguity if some assignments to x use the rebind keyword and others don't. Then there's a local x and also a nonlocal x. When x is used in an expression (even on the RHS of a rebind statement!) it would be interpreted as the local one. My gut feeling is that most code that wants to use this feature only wants to use it in a few places. A good example is fcgi.py (implements WSGI for FastCGI), where they use a mutable array to store a flag indicating whether or not the headers have already been sent. Then let's allow nonlocal x = 12 as a shortcut for nonlocal x x = 12 Bash users should be familiar with this from e.g. export FOO=bar. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Evan Simpson wrote: I'd like to toss one more variant into the mix. If we really need to address variables in an intermediate scope, the most explicit way that I can think of doing so is to write (using Philip's example): def counter(num): scope as outer # outer is an arbitrary identifier def inc(): outer.num += 1 return outer.num return inc This is somewhat similar to the unworkable use the function name method that's been suggested. The scope as X statement associates the name X with the namespace of local variables in the scope in which it is executed. Such names are lexically scoped, and only allow access to or rebinding of existing names from the originating scope (i.e. no del outer.num allowed). Why couldn't at least augmented assignment be implicitly rebinding? It has been suggested before (in the context of a rebinding operator), but I'm wondering, is this also off the table? def counter(num): def inc(): num += 1 return num return inc Reads very natural to me. It's likely the most frequent example of what people try before they learn that rebinding to outer scopes isn't allowed. It could Just Work. Just ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
[EMAIL PROTECTED] wrote: jan-python So.. are we only thinking about implementing this outer jan-python scope assignment because there's lots of talk about it on jan-python the list, ... :-) jan-python ... or are there actually use cases that would become jan-python clearer if assigning to an outer scope variable was allowed? I think full lexical scoping will only be of use to people who use nested scopes heavily. The more typical user will be happy to just refer to values in outser scopes without modifying them and rely on classes to save changed state across calls. I think it's almost a YAGNI, but I'm sure others will disagree. I think it falls into the same category as Guido's ultimate acceptance of PEP 308. There are assorted ways to live *without* conditional expressions, but each of the workarounds for its absence had issues. Switching to a statement worked properly, but meant you didn't have a single expression any more. Use the and-or trick kept the single expression characteristic, but was easy to get wrong. Hence, PEP 308: One Obvious Way to do it, assuming you want to do it in the first place. I think writing to outer scopes is similar. You can box the variable, or make it an attribute of an object, but either approach requires you to refactor *all* uses of the variable, rather than just the one you currently care about. Hence, 'nonlocal': One Obvious Way to do it, assuming you want to do it in the first place. That way, when you're *reading* the code of someone who likes to use such tricks, you only need to know how to read the one obvious way, rather than having to decipher whichever method they've chosen to work around the limitation. The perennial accumulator example still takes 6 lines, though: def accumulator(n): def increment(i): nonlocal n n += i return n return increment Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://www.boredomandlaziness.org ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Just van Rossum wrote: Why couldn't at least augmented assignment be implicitly rebinding? It has been suggested before (in the context of a rebinding operator), but I'm wondering, is this also off the table? def counter(num): def inc(): num += 1 return num return inc Reads very natural to me. It's likely the most frequent example of what people try before they learn that rebinding to outer scopes isn't allowed. It could Just Work. note that most examples of this type already work, if the target type is mutable, and implement the right operations: def counter(num): num = mutable_int(num) def inc(): num += 1 return num return inc maybe we should consider adding mutable strings and mutable numbers to Python 3.0 ? and a mutable built-in, that does the opposite of the freeze stuff: def counter(num): num = mutable(num) def inc(): num += 1 return num return inc (what is this thread doing on python-dev, btw? shouldn't it be over at the 3000 list, so I can enjoy my vacation without being drawn into yet another endless discussion thread ;-) /F ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Kevin Jacobs [EMAIL PROTECTED] wrote: Why not extend the interface to the locals builtin and add a __getitem__ that returns a proxy to access locals defined in other lexical scopes via __{get/set/del}attr_: def counter(num): num = 1 def inc(): locals[1].num += 1 return outer.num return inc Where, for CPython, locals[n] gives access to NamespaceProxy(sys._getframe(n).f_locals). Two nits: First, I suspect that you meant to write return locals[1].num. Second, sys._getframe doesn't do what you want, here. It reaches back up the call chain, not out into lexically containing scopes. That said, I like the idea of giving locals[] the meaning you intended. It has the advantage of not adding any new keywords or syntactic constructs, but the disadvantage of not explicitly signaling that locals in a given scope will be twiddled elsewhere. Also, for efficiency's sake, it might be desirable to only allow a literal integer as the index, and to deal with use of locals[] at compile time rather than dynamically. I'm not sure how much overhead would be involved in enabling dynamic lookup of arbitrary lexically containing scopes, but I would *not* want to enable stuff like locals[i * 2 - 1]. Cheers, Evan @ 4-am ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 09:56 PM 7/6/2006 -0400, Kevin Jacobs [EMAIL PROTECTED] wrote: Why not extend the interface to the locals builtin and add a __getitem__ that returns a proxy to access locals defined in other lexical scopes via __{get/set/del}attr_: def counter(num): num = 1 def inc(): locals[1].num += 1 return outer.num return inc Where, for CPython, locals[n] gives access to NamespaceProxy(sys._getframe(n).f_locals). That doesn't actually work, because sys._getframe(1) will give you inc()'s caller, *not* the frame where it was defined. In addition to having a relatively pleasing and explicit syntax, this may be a feasible method for allowing portable introspection into outer scopes without having to export the whole frame object a la sys._getframe(n). I strongly suspect that Jython, IronPython, and PyPy would have little difficulty supporting (and optimizing) this construct. Lacking core language support, it is easy to roll an object that does just what I suggest. Actual implementation is left to a more motivated reader, of course. While I hesitate to describe anything as impossible, I will note that an implementation with the syntax you suggest is not likely to be possible without resorting to ctypes or a C module, because the frame doesn't have a reference to the function, only the code object, and it's the function objects that own the closure cells. I think the only way you can reasonably accomplish rebinding in Python right now is to have a rebind(func, var=value) function, e.g.: def counter(num): def inc(): rebind(inc, num=num+1) return num return inc It doesn't allow augmented assignment, of course, and it also creates a circular reference between 'inc' and itself, requiring garbage collection to clean up. Anyway, the actual implementation of such a rebind function would basically be a bit of syntax sugar over this cookbook recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440515 You'd want to just use the keyword argument names to figure out which cells of the function needed changing. And the whole thing would be really slow and complex. You'd probably be better off using function attributes: def counter(num): def inc(): inc.num+=1 return inc.num inc.num = num return inc It's not ideal, but *this* should probably be the pattern we recommend for rebinding, rather than create a class or use an anonymous namespace argument. It can even be prettied up a little bit with a decorator to set the function attributes. def counter(num): @uses(num=num) def inc(): inc.num+=1 return inc.num return inc But that's about as good as it gets, which is nowhere near as good as: def counter(num): def inc(): nonlocal num num+=1 return num return inc On the other hand, the rebind() syntax actually is slightly cleaner in some respects: def counter(num): def inc(): rebind(num = num+1) return num return inc Maybe we should just make rebind() a fast builtin. ;) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido Well, personally I'm for allowing full rebinding semantics but Guido only when a 'global' (or 'nonlocal') statement is used Guido first. Making augmented assignment automatically imply 'global' Guido etc. seems too magical to me. So, if I understand correctly, in the presence of a global statement search just goes up the lexical chain looking for the first occurrence of the variable to modify? x = 0 def f(): x = 1 def g(): global x x = 2 print x g() print x f() print x Today it prints 2 1 2 You're suggesting it will print 2 2 0 ? Sounds reasonable to me. If we're talking py3k I'd chuck global as a keyword though and replace it with something like outer. Skip ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/8/06, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Guido Well, personally I'm for allowing full rebinding semantics but Guido only when a 'global' (or 'nonlocal') statement is used Guido first. Making augmented assignment automatically imply 'global' Guido etc. seems too magical to me. So, if I understand correctly, in the presence of a global statement search just goes up the lexical chain looking for the first occurrence of the variable to modify? x = 0 def f(): x = 1 def g(): global x x = 2 print x g() print x f() print x Today it prints 2 1 2 You're suggesting it will print 2 2 0 ? Right. And if the search finds no scope that defines x, it's a compile-time error (that's also new). Sounds reasonable to me. If we're talking py3k I'd chuck global as a keyword though and replace it with something like outer. This is still under debate. I don't think we ought to change this in Python 2.x until we've settled on the 3.x syntax and semantics; eventually (in Python 2.9 or so :-) we can backport it with a __future__ statement. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Phillip J. Eby wrote: At 07:27 PM 7/5/2006 +0200, Guido van Rossum wrote: However I still don't believe global has the stretchiness in its meaning that you claim it has. Have you ever heard a Python programmer talking about closures use the word global variable? Are there any other native speakers who side with Michael? I don't, and am -1 on using global to mean outer. Another -1 on stretching the meaning of global here. I quite like 'nonlocal', though. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://www.boredomandlaziness.org ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Michael Chermside [EMAIL PROTECTED] writes: Phillip Eby writes: I don't see a problem with requiring '.x' to be used for both reading and writing of outer-scope names; it just shouldn't be required for an outer-scope name that you don't rebind in the current scope. def counter(num): def inc(): .num += 1 return .num return inc I am reminded of Tim Peter's declaration in response to a similar proposal some time ago: Syntax should not look like grit on my monitor. (Sorry, no reference... but I swear it's word-for-word accurate because the quote burned itself into my memory.) I think it was Anthony: http://mail.python.org/pipermail/python-dev/2005-July/054581.html Cheers, mwh -- SCSI is not magic. There are fundamental technical reasons why it is necessary to sacrifice a young goat to your SCSI chain now and then. -- John Woods ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Ka-Ping Yee wrote: On Wed, 5 Jul 2006, Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Using the classic nonsense example: def counter(num): def inc(): .num += 1 return .num return inc Would this also use ..num to refer to num in an outer scope two levels removed? I don't think there's any need for that. I see '.num' as just another way of saying num, but don't make a new binding. I agree with Guido that the best proposals so far are converging on the idea that it's more Pythonic to say don't make a new binding when a variable is used, than to declare this is the scope for this binding ahead of time. Of those there are two kinds: (a) State once (anywhere in a scope, but preferably at the beginning) that a variable is non-local. This is like the global keyword works now, and this category includes: - Change the meaning of 'global'. - Add a new keyword 'outer' or 'nonlocal', etc. (b) Indicate, when mentioning a variable, that the variable is non-local. This category includes: - Say 'global.x' or 'outer.x' instead of 'x'. - Say '.x' instead of 'x'. My favourite so far is to use a new keyword -- i think changing the meaning of 'global' would be misleading. '.x' is probably my next favourite, though i share Guido's concern about allowing both 'x' and '.x' to refer to the same thing. I see that 'outer' is used as an identifier in hmac.py in the standard library and also as a variable in test_set*.py. On the other hand 'nonlocal' does not appear anywhere in the standard library. Thus, 'nonlocal' is the best option that i've seen so far; it's less likely to break anything and it says exactly what it means. I can't think of a more accurate keyword. 'extant' (= already existing) is probably pretty rare in existing code, and has pretty close to exactly the correct meaning, but may be too obscure. -tim -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/python-python-dev%40m.gmane.org ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
So.. are we only thinking about implementing this outer scope assignment because there's lots of talk about it on the list, or are there actually use cases that would become clearer if assigning to an outer scope variable was allowed? I tend to think that almost _any_ piece of code that could be written using outer scope assignment would become less clear by doing so as opposed to some other way. So, I'm not keen on the whole idea. If we must, however, I think a declaration like 'nonlocal' would be best (well, least-bad, that is). ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
jan-python So.. are we only thinking about implementing this outer jan-python scope assignment because there's lots of talk about it on jan-python the list, ... :-) jan-python ... or are there actually use cases that would become jan-python clearer if assigning to an outer scope variable was allowed? I think full lexical scoping will only be of use to people who use nested scopes heavily. The more typical user will be happy to just refer to values in outser scopes without modifying them and rely on classes to save changed state across calls. I think it's almost a YAGNI, but I'm sure others will disagree. Skip Repeat after me: Python is not Lisp... ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
However I still don't believe global has the stretchiness in its meaning that you claim it has. Have you ever heard a Python programmer talking about closures use the word global variable? I guess the term I've heard most often is free variable, but I wouldn't be surprised if I saw the term global used to describe a free variable. However, I should point out that Dijkstra used global in a similar way in his 1971 book A Discipline of Programming. The program examples in that book are in a language he devised for the purpose; one of the language's features is that every variable used in every block must be explicitly declared, even if it is taken from a surrounding block. If I remember correctly, the terms he used for variables taken from a surrounding block and variables defined and used in the same block were global and private, respectively. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/6/06, Guido van Rossum [EMAIL PROTECTED] wrote: +1 on nonlocal.I think that the := operator is also in case (b), but as I don't likeit I'm find with not mentioning it. :-)Could someone write a PEP for this? Doesn't have to be very long butI'd like it to summarize the main options proposed and discuss them, like I did for the switch PEP. It's a p3yk PEP. (We really need tomove this to the py3k list...)Drat, too bad this wasn't back in February when I was all for writing the PEP--sadly, I don't have time to do this, maybe later if no one steps up to the plate... For reference, here is a link to the other, rather large, thread on this back then:http://thread.gmane.org/gmane.comp.python.devel/76532/focus=76532 My option one, is essentially nonlocal, though I spelled it as use. Really, I am personally agreeable to almost any spelling of such a keyword. I am +1 on nonlocal, though I know the biggest dissent against it is adding another global-like keyword that is not pythonic. Also in regard to the prefix-dot notation (i.e. .x), I am -1 for the reason that it introduces a subtle alternate way of spelling local variables. The rules for the usage would have to be strict enough to prevent subtle code obscurity (like what is the semantics for using .x and x in a scope--are both spellings allowed, and if so, what is the meaning if assignment is involved or is not involved). Of course, if the semantics were well defined such that it would be difficult for users to trap themselves with different spellings of local variables, then I would be +0 for it. Best Regards,Almann-- Almann T. Goo[EMAIL PROTECTED] ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 10:05 AM 7/6/2006 -0500, [EMAIL PROTECTED] wrote: jan-python So.. are we only thinking about implementing this outer jan-python scope assignment because there's lots of talk about it on jan-python the list, ... :-) jan-python ... or are there actually use cases that would become jan-python clearer if assigning to an outer scope variable was allowed? I think full lexical scoping will only be of use to people who use nested scopes heavily. The more typical user will be happy to just refer to values in outser scopes without modifying them and rely on classes to save changed state across calls. I think it's almost a YAGNI, but I'm sure others will disagree. Here's the reason I think this keeps coming up, and why Guido's just use a class argument doesn't really address the actual problem that's taking place. When you are writing some function, and you find yourself using a nested function because it's the closest match for something you're doing, there occasionally comes a point at which you realize that, gosh, you need to mutate something in an outer scope. At that point, your choices are to either kludge it with a mutable, or to reorganize the whole thing. Both of these *feel* like warts because they're making you do less-than-optimal things. Your mental flow is disrupted because the language is forcing you to work around it, rather than having a way of working with it. This is a user experience issue, not a technical one. The fact that you can say, you should've done it differently in the first place doesn't do anything for your flow. In theory, you could design cars without any brakes, because people could just coast to a stop if they planned well enough in advance. ;-) In practice, you need the brakes because people often don't discover their need to stop until much later in the process. This is a flow issue that's specific to *incremental* development. What happens is that first you refactor the code in a function to include nested functions. The variable references don't change, you're just indenting some code. *Then*, it later comes up that you need to rebind a variable, and now you have to globally change the variable to make it work as a mutable instead, or else you have to refactor all the variables to be 'self.' references and put a class in somewhere. This destroys the flow of incrementally developing whatever it is you're developing, and makes you stop to do excise work. That's why being able to rebind a variable without redefining it is important. In short: in *theory*, a rebinding operator or nonlocal declaration is unnecessary. In *practice*, having one seems quite useful every time you wander down the path that leads to having to rewrite your code just because the language won't let you do that one tiny thing -- or so it feels like to the person who's experiencing it. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Talin wrote: I propose to create a new type of scoping rule, which I will call explicit lexical scoping, that will co-exist with the current implicit scoping rule that exists in Python today. I'd like to toss one more variant into the mix. If we really need to address variables in an intermediate scope, the most explicit way that I can think of doing so is to write (using Philip's example): def counter(num): scope as outer # outer is an arbitrary identifier def inc(): outer.num += 1 return outer.num return inc This is somewhat similar to the unworkable use the function name method that's been suggested. The scope as X statement associates the name X with the namespace of local variables in the scope in which it is executed. Such names are lexically scoped, and only allow access to or rebinding of existing names from the originating scope (i.e. no del outer.num allowed). Cheers, Evan @ 4-am ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Thu, 06 Jul 2006 18:28:12 +0200, Phillip J. Eby [EMAIL PROTECTED] wrote: Here's the reason I think this keeps coming up, and why Guido's just use a class argument doesn't really address the actual problem that's taking place. I agree this argument is not generally applicable in every case, but why not in this specific situation? In short: in *theory*, a rebinding operator or nonlocal declaration is unnecessary. In *practice*, having one seems quite useful every time you wander down the path that leads to having to rewrite your code just because the language won't let you do that one tiny thing - I think this argument is a too general one. To me it is too close to let's add every possible feature we can find, because it might be usefull to someone :) One of the things I like about python is that it doesn't do this, and therefore the manual stays relatively small and I don't have to remember all kinds of rarely used features to make best use of the language. (I assume this is not a point of debate. repeating: Python is not Lisp ;-) ) Most of the arguments I've seen on the list are about 'how can we implement this', I'd like to see more arguments on whether this should be implemented at all. I was hoping someone would come up with a good example, so does anyone have one?? - or so it feels like to the person who's experiencing it. Have you ever been that person, or come across such a situation? O, and I don't think the inc() example is a good one. In this incrementer the function call is all about the side effects, it's even in the name 'increment'. Incrementing is useless unless you increment /something/, so this should be better implemented as a class. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 01:00 AM 7/7/2006 +0200, Jan Kanis wrote: On Thu, 06 Jul 2006 18:28:12 +0200, Phillip J. Eby [EMAIL PROTECTED] wrote: Here's the reason I think this keeps coming up, and why Guido's just use a class argument doesn't really address the actual problem that's taking place. I agree this argument is not generally applicable in every case, but why not in this specific situation? I'm saying that just use a class doesn't help in the incremental case. If you happen to know *ahead of time* that you will need a callback to modify state, you can perhaps do this, just like you can always coast your car to a stop if you have enough advance notice. However, sometimes you really want to have brakes. :) In short: in *theory*, a rebinding operator or nonlocal declaration is unnecessary. In *practice*, having one seems quite useful every time you wander down the path that leads to having to rewrite your code just because the language won't let you do that one tiny thing - I think this argument is a too general one. To me it is too close to let's add every possible feature we can find, because it might be usefull to someone :) Not at all. It's an argument regarding the incremental evolution of code. Python tries to keep the growth of complexity in a code base relatively flat -- incremental effort should be rewarded with incremental benefit. Discontinuities of complexity are to be avoided. The classic example is Hello world, where in Java you must learn about six or eight different things, but in Python it is just 'print Hello world'. If you want to then make it a function, you indent it and add a 'def'. It is all very minimal and incremental, and for the most part, the things that people want to add to Python tend to be wherever discontinuities can occur. It is also true that, because Python is already so well-designed, that these remaining feature areas tend to lean toward the minor and/or obscure: coroutines, conditional expressions, etc. etc. One of the things I like about python is that it doesn't do this, and therefore the manual stays relatively small and I don't have to remember all kinds of rarely used features to make best use of the language. (I assume this is not a point of debate. repeating: Python is not Lisp ;-) ) And one of the things that makes it not Lisp is that not everyone is free to go around and actually add the new syntax to support their use cases. Guido must first be convinced. Discussions like this one are how we convince him. ;) - or so it feels like to the person who's experiencing it. Have you ever been that person, or come across such a situation? Many times. The hard thing about trying to provide use cases for this is that of course you can always find another way to write it. It's just that sometimes the nested function is a perfect solution at point in time A, and then at point in time B, a change in the program requires that the nested function mutate a bit of state, resulting in either a rewrite to do it the right way, or hacking mutable objects. Both are user-experience discontinuities: a sudden sharp rise in effort compared to reward. This then produces the perception of a wart. Yes, it's purely a superficial problem. That's why it's called a wart. :) O, and I don't think the inc() example is a good one. In this incrementer the function call is all about the side effects, it's even in the name 'increment'. Incrementing is useless unless you increment /something/, so this should be better implemented as a class. Any example that's intended to motivate lexical scope modification is going to suffer from either being bogus due to oversimplification, or confusing due to application-specificity. That doesn't make it something that doesn't happen, it's just that the circumstances of it happening are somewhat more organic. By the way, I'm leaving out the people who have backgrounds in Lisp or Scheme and are trying to write it in Python. I don't really care for Lisp, myself, although my Python has become increasingly functional over time. Not because of Lisp (which I've never used apart from a few Emacs hacks 12 years ago, when I didn't even know what functional programming *was*), but because it's often the easiest way to do something. At least, until you bump into the rebinding problem. Personally, the idea to use a simple namespace object to store mutable variables as attributes seems rather appealing as a workaround solution in the absence of a rebinding operator. The other solution I thought of was providing a function called 'rebind()' that could be used like this: rebind(x=23) to change 'x' in the nearest enclosing scope. This solves the problem without adding any syntax, and it's incremental at the point of use. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe:
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Fri, 07 Jul 2006 01:25:19 +0200, Phillip J. Eby [EMAIL PROTECTED] wrote: - or so it feels like to the person who's experiencing it. Have you ever been that person, or come across such a situation? Many times. The hard thing about trying to provide use cases for this is that of course you can always find another way to write it. It's just that sometimes the nested function is a perfect solution at point in time A, and then at point in time B, a change in the program requires that the nested function mutate a bit of state, resulting in either a rewrite to do it the right way, or hacking mutable objects. Well, not an actual example, but close enough. Leaving the rest to Guido then. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/6/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Here's the reason I think this keeps coming up, and why Guido's just use a class argument doesn't really address the actual problem that's taking place. (And note that I've recently gone on record as doubting that argument myself.) When you are writing some function, and you find yourself using a nested function because it's the closest match for something you're doing, there occasionally comes a point at which you realize that, gosh, you need to mutate something in an outer scope. At that point, your choices are to either kludge it with a mutable, or to reorganize the whole thing. Both of these *feel* like warts because they're making you do less-than-optimal things. Your mental flow is disrupted because the language is forcing you to work around it, rather than having a way of working with it. Right. I'm actually not a big fan of the word flow -- it often doesn't apply to the way I work myself, and it tends to emphasize the needs of the writer at the expense of the reader. (Perl programmers have excellent flow due to the many ways of doing things in that language. 'nuff said.) But I agree that the need for a refactoring like this to be a simple, local thing is important. (Compare my argument for making print a function -- which by the way received an applause at EuroPython once I explained it, after getting boohs when the slide first went up.) This is a user experience issue, not a technical one. The fact that you can say, you should've done it differently in the first place doesn't do anything for your flow. In theory, you could design cars without any brakes, because people could just coast to a stop if they planned well enough in advance. ;-) In practice, you need the brakes because people often don't discover their need to stop until much later in the process. I don't like the brakeless car example either. It is too extreme and opens your argument up to easy objections (the similarity between the cases isn't that great anyway). This is a flow issue that's specific to *incremental* development. What happens is that first you refactor the code in a function to include nested functions. The variable references don't change, you're just indenting some code. *Then*, it later comes up that you need to rebind a variable, and now you have to globally change the variable to make it work as a mutable instead, or else you have to refactor all the variables to be 'self.' references and put a class in somewhere. This destroys the flow of incrementally developing whatever it is you're developing, and makes you stop to do excise work. That's why being able to rebind a variable without redefining it is important. Quite apart from the coder's flow, if the code is being developed incrementally, there are probably readers reviewing it before and after the refactoring. It's a lot easier to verify that a refactoring is correct when it doesn't choose a completely different approach. In short: in *theory*, a rebinding operator or nonlocal declaration is unnecessary. In *practice*, having one seems quite useful every time you wander down the path that leads to having to rewrite your code just because the language won't let you do that one tiny thing -- or so it feels like to the person who's experiencing it. There really is hardly any need to argue the point any more; I've said that I will accept the feature if we can find a mutually acceptable syntax. I still only see these two alternatives as viable: a new keyword (nonlocal being my current favorite) or stretching the meaning of global. After Andrew Koenig's Dijkstra reference I'm beginning to think that the latter may actually be fine. (Oh, and somebody can add get rid of global to PEP 3099 -- that ain't gonna happen. :-) -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/6/06, Evan Simpson [EMAIL PROTECTED] wrote: Talin wrote: I propose to create a new type of scoping rule, which I will call explicit lexical scoping, that will co-exist with the current implicit scoping rule that exists in Python today. I'd like to toss one more variant into the mix.If we really need toaddress variables in an intermediate scope, the most explicit way that Ican think of doing so is to write (using Philip's example): def counter(num):scope as outer # outer is an arbitrary identifierdef inc():outer.num += 1return outer.numreturn incWhy not extend the interface to the locals builtin and add a __getitem__ that returns a proxy to access locals defined in other lexical scopes via __{get/set/del}attr_: def counter(num): num = 1def inc(): locals[1].num += 1return outer.numreturn incWhere, for CPython, locals[n] gives access to NamespaceProxy(sys._getframe(n).f_locals). In addition to having a relatively pleasing and explicit syntax, this may be a feasible method for allowing portable introspection into outer scopes without having to export the whole frame object a la sys._getframe(n). I strongly suspect that Jython, IronPython, and PyPy would have little difficulty supporting (and optimizing) this construct. Lacking core language support, it is easy to roll an object that does just what I suggest. Actual implementation is left to a more motivated reader, of course.Just another crazy idea to throw into the pot. -Kevin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 05:49 AM 7/5/2006 +0200, Guido van Rossum wrote: * Alternate spelling of outer names when binding (e.g. .x = whatever to bind an outer x) We looked at and rejected globals.x = whatever. I think the same reasoning applies here. I thought the 'globals.x' proposal required that 'x' always be accessed using 'globals', even if it wasn't being rebound. I don't see a problem with requiring '.x' to be used for both reading and writing of outer-scope names; it just shouldn't be required for an outer-scope name that you don't rebind in the current scope. That symmetry requirement can't be implemented with the 'globals.x' approach unless 'globals' is treated specially by the compiler. Using the classic nonsense example: def counter(num): def inc(): .num += 1 return .num return inc If inc() only needed to *read* num, it could just use 'num' without the '.', and be nicely backward compatible with today's Python. (Note: It should be illegal to use both '.num' and 'num' in the same scope, whether writing or reading the value, to prevent readers from becoming confused about what variable you mean. It should also be required that the compiler can see a definition of 'num' in an outer scope if you use the '.num' syntax, so that misspelling a name doesn't create a global variable.) I personally think this approach could be the overall least-intrusive solution as far as syntax goes. It also allows for dropping the 'global' keyword in 3.x, and it has a nice EIBTI feel to it, as it allows you to highlight closure variables in an inner function by using the '.'. It's often not obvious when an inner function (such as a decorator returned by a decorator factory) is using variables that were defined in the outer scope; the leading '.' would make them stand out, and so could be considered the recommended code style when referring to outer variables. In addition, there's a nice symmetry between nested functions and top-level functions, e.g. in this global version of the counter example: num = 0 def inc(): .num += 1 return .num The principle downside taht I see is that it uses semi-random punctuation in place of keywords. OTOH, we are already using more-or-less this syntax for relative imports, so reusing it to mean relative variables seems to at least avoid creating any entirely new principles. :) Anyway, I won't argue this one further; I just wanted to make sure it had been considered, as I'm not sure that you were reading the thread where it was first brought up (possibly as long as a few months ago). ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: At 05:49 AM 7/5/2006 +0200, Guido van Rossum wrote: * Alternate spelling of outer names when binding (e.g. .x = whatever to bind an outer x) We looked at and rejected globals.x = whatever. I think the same reasoning applies here. I thought the 'globals.x' proposal required that 'x' always be accessed using 'globals', even if it wasn't being rebound. I don't see a problem with requiring '.x' to be used for both reading and writing of outer-scope names; it just shouldn't be required for an outer-scope name that you don't rebind in the current scope. That symmetry requirement can't be implemented with the 'globals.x' approach unless 'globals' is treated specially by the compiler. Using the classic nonsense example: def counter(num): def inc(): .num += 1 return .num return inc If inc() only needed to *read* num, it could just use 'num' without the '.', and be nicely backward compatible with today's Python. (Note: It should be illegal to use both '.num' and 'num' in the same scope, whether writing or reading the value, to prevent readers from becoming confused about what variable you mean. It should also be required that the compiler can see a definition of 'num' in an outer scope if you use the '.num' syntax, so that misspelling a name doesn't create a global variable.) I personally think this approach could be the overall least-intrusive solution as far as syntax goes. It also allows for dropping the 'global' keyword in 3.x, and it has a nice EIBTI feel to it, as it allows you to highlight closure variables in an inner function by using the '.'. It's often not obvious when an inner function (such as a decorator returned by a decorator factory) is using variables that were defined in the outer scope; the leading '.' would make them stand out, and so could be considered the recommended code style when referring to outer variables. In addition, there's a nice symmetry between nested functions and top-level functions, e.g. in this global version of the counter example: num = 0 def inc(): .num += 1 return .num The principle downside taht I see is that it uses semi-random punctuation in place of keywords. OTOH, we are already using more-or-less this syntax for relative imports, so reusing it to mean relative variables seems to at least avoid creating any entirely new principles. :) Anyway, I won't argue this one further; I just wanted to make sure it had been considered, as I'm not sure that you were reading the thread where it was first brought up (possibly as long as a few months ago). Thanks for bringing this up. I'm not sure what I think of it yet. One problem I see is that there might end up being two ways to reference variables in outer scopes: .num if you plan to assign to it, or just num if you only reference it. I find that the most disurbing issue so far; modified global declarations or outer declarations don't have this problem. Would this also use ..num to refer to num in an outer scope two levels removed? -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Wednesday 05 July 2006 18:21, Guido van Rossum wrote: Would this also use ..num to refer to num in an outer scope two levels removed? Ew! I don't want to even think about debugging ...x vs x Anthony -- Anthony Baxter [EMAIL PROTECTED] It's never too late to have a happy childhood. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Sorry, I should have added a wink... :-) On 7/5/06, Anthony Baxter [EMAIL PROTECTED] wrote: On Wednesday 05 July 2006 18:21, Guido van Rossum wrote: Would this also use ..num to refer to num in an outer scope two levels removed? Ew! I don't want to even think about debugging ...x vs x Anthony -- Anthony Baxter [EMAIL PROTECTED] It's never too late to have a happy childhood. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: At 12:18 AM 7/5/2006 +0200, Guido van Rossum wrote: I don't see anything else that's attractive. The realistic options are: 1. do nothing 2. extend global's meaning 3. add outer keyword Did you also consider and reject: * Alternate binding operators (e.g. :=, .=, etc.) Brr. * Alternate spelling of outer names when binding (e.g. .x = whatever to bind an outer x) We looked at and rejected globals.x = whatever. I think the same reasoning applies here. If so, then these should probably be added to the rejected alternatives for Py3K so they don't get rehashed. Georgbot? I added the alternative binding operators. The discussion about .x seems to be still in progress. Georg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum wrote: Would this also use ..num to refer to num in an outer scope two levels removed? I realize this was a wink, but it is a valid problem with the dot-proposal. def foo(n): def bar(n): def baz(): return .n So, which 'n' outer 'n' is being referenced? Seems like you need to either be able to do multiple dots (ugly, hard to read) or only do a single-step outwards reference. But then that has it's own problems, if I meant the 'n' passed into 'foo', then I have to resort to such nonsense as: def foo(n): def bar(n): foon = .n def baz(): return .foon It would almost be cute if you could do something like .foo.n to get to the correct variable. If python maintains it's current scoping rules, then it seems like it works out, but I haven't thought this one all the way through. def foo(n): def bar(n): def baz(): return .foo.n + .bar.n -- Scott Dial [EMAIL PROTECTED] [EMAIL PROTECTED] ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum [EMAIL PROTECTED] wrote: 1. do nothing 2. extend global's meaning 3. add outer keyword 2.5. extend global syntax to cover both [really global] and [innermost matching scope]. eg. global x, y outer # trailing non-keyword global in x, y # re-use keyword not global x# ceci n'est pas un global ... # something less ugly? Personally it's not a burning need Agreed. Inability to write as well as read nested scopes is more of an aesthetic wart than a practical one IMO. -- And Clover mailto:[EMAIL PROTECTED] http://www.doxdesk.com/ -- And Clover mailto:[EMAIL PROTECTED] http://www.doxdesk.com/ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Did you also consider and reject: * Alternate binding operators (e.g. :=, .=, etc.) Brr. That's too bad :( I still find a rebinding operator (:= being my favorite) much, *much* more appealing than any of the alternative proposals. It's beautifully symmetrical with assignment means local. It also pretty much makes the global statement redundant. The only downside I see is that it may cause a fairly big shift in style: I for one would use := for rebinding local names. While I think that would be an improvement (eg. by catching typo's earlier), it's *different*. Just -- Change is bad. We fear change. -- Garth Algar ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/5/06, Just van Rossum [EMAIL PROTECTED] wrote: Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Did you also consider and reject: * Alternate binding operators (e.g. :=, .=, etc.) Brr. That's too bad :( I still find a rebinding operator (:= being my favorite) much, *much* more appealing than any of the alternative proposals. It's beautifully symmetrical with assignment means local. It also pretty much makes the global statement redundant. The only downside I see is that it may cause a fairly big shift in style: I for one would use := for rebinding local names. While I think that would be an improvement (eg. by catching typo's earlier), it's *different*. Hallo broer! :-) I wonder what this should mean then: def outer(): def inner(): x := 1 What is x's scope? Also, a := operator allows all sorts of left-hand sides that don't necessarily make sense, e.g. x.foo := 1 x[0] := 1 -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
2006/7/5, Just van Rossum [EMAIL PROTECTED]: Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Did you also consider and reject: * Alternate binding operators (e.g. :=, .=, etc.) Brr. That's too bad :( I still find a rebinding operator (:= being my favorite) much, *much* more appealing than any of the alternative proposals. It's beautifully symmetrical with assignment means local. It also pretty much makes the global statement redundant. The only downside I see is that it may cause a fairly big shift in style: I for one would use := for rebinding local names. While I think that would be an improvement (eg. by catching typo's earlier), it's *different*. delurk I suggest - as an assignment operator instead of := - it's used in OCaml and it looks *very* different, yet still makes sense. x = 0 print x def f(): x = 1 # bind locally print x def g(): x - 42 # assign lexically print x f() print x g() print x prints 0 1 0 42 42 /delurk ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Guido van Rossum wrote: Hallo broer! :-) Yo :) I wonder what this should mean then: def outer(): def inner(): x := 1 What is x's scope? UnboundVariableError: variable 'x' referenced before assignment Or a SyntaxError if the compiler can detect it. Also, a := operator allows all sorts of left-hand sides that don't necessarily make sense, e.g. x.foo := 1 x[0] := 1 True, although maybe they could be made to make sense by defining special methods: __rebindattr__ __rebinditem__ 0.5 wink Just ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
I know this is very similar to the global.x = syntax, which was already shot down?, but wouldn't allowing access to a functions locals from within, by prefixing the name, be a good way to disambiguate what happens (instead of any operator to indicate outer scope, like .x = 3 or the like)? I guess this necessitates global.x = as well, though. def foo(): def bar(): foo.x = 3 print x # prints 3 I seem to recall that this syntax has been proposed before, though not in this discussion. But my memory is murky. //Simon ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Marek Baczek Baczyñski wrote: I suggest - as an assignment operator instead of := - it's used in OCaml and it looks *very* different, yet still makes sense. Except it's currently valid Python syntax: x = 0 x - 42 False Just ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Barry Clearly we need the as if in operator: Why not be more direct? x = 0 def foo(): x = 1 def bar(): x = 2 def baz(): x in foo = 3 x in global += 1 By naming the function in which the binding is to occur you avoid problems of someone coming along and adding or deleting functions between the assignment (in baz) and the target of the assignment (x in foo) but then forgetting to increment or decrement the counters that refer to a fixed number of levels above the current function. Barry (Personally, I've never really needed this much, but if you have Barry to have it, be explicit! :) Nor I. I can't think of any situations in my programming where I've used nested functions, but I was never a LISPer... Skip ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 5 jul 2006, at 11.40, Scott Dial wrote: Guido van Rossum wrote: Would this also use ..num to refer to num in an outer scope two levels removed? I realize this was a wink, but it is a valid problem with the dot-proposal. def foo(n): def bar(n): def baz(): return .n So, which 'n' outer 'n' is being referenced? Seems like you need to either be able to do multiple dots (ugly, hard to read) or only do a single-step outwards reference. But then that has it's own problems, if I meant the 'n' passed into 'foo', then I have to resort to such nonsense as: snip No, it's actually not a problem. foo()'s n should just be hidden. If you don't want it to be hidden, don't write your function that way. If you find you need deeply nested functions where local names shadow names in outer scopes that you need to access you might want to think of another way to solve your problem. //Simon ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On Jul 5, 2006, at 9:39 AM, [EMAIL PROTECTED] wrote: Barry Clearly we need the as if in operator: Why not be more direct? Sure, why not? :) Then we can reserve the as if operator for those things that Guido has rejected, but that we sneak in while he's not looking. like-omg-gag-me-with-a-spoon-ly y'rs, - -Barry -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) iQCVAwUBRKvK8nEjvBPtnXfVAQLbswQArfvIoCdCHmryk3qkOvG6BE0Q1iW7dk0O eI178nG1tY+02JLyrPb1RcjdJG0W0wPwugvVNwVlz29cNkt048uEme6ZBfv3wCt/ bQSWTnDym/OWtQhUtsaw7V5K1o/bP5noqS2MQAcafk4lARv7TAWbBNkPqpk/yFmp 2yNhIfngjts= =thYd -END PGP SIGNATURE- ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 10:21 AM 7/5/2006 +0200, Guido van Rossum wrote: Thanks for bringing this up. I'm not sure what I think of it yet. One problem I see is that there might end up being two ways to reference variables in outer scopes: .num if you plan to assign to it, or just num if you only reference it. I find that the most disurbing issue so far; modified global declarations or outer declarations don't have this problem. Well, you could make it mandatory in Py3K I suppose, though I'm not sure I like it being mandatory, due to the frequent need to reference top-level names that would cause an awful lot of dots to start popping up. But for existing Python, the optional nature of the '.' allows existing code to run unchanged. And for versions that support the new syntax, using a leading '.' for all non-global, non-locals should be considered good style since it highlights the dependency and practically shouts tricky stuff here, pay attention. Ironically, having *only* one way to refer to outer variables makes it impossible to communicate this distinction in the common read-only case. Would this also use ..num to refer to num in an outer scope two levels removed? I think that's unnecessary; it would be much better to use variables with distinct names. By the way, an interesting thought for Py3K is that you could maybe use this syntax to do away with explicit 'self', if you consider the class' namespace to be part of a function's closure. E.g.: class Foo: whee = 42 def bar(baz): print .whee Consider this: if Foo were a function rather than a class, each invocation of Foo would yield a new namespace in which 'whee' is defined. However, each invocation of a *class* also yields a new namespace. So there's a definite symmetry in using .whee to refer to an instance attribute of Foo. The big problem that comes to mind with that idea is that it makes it impossible to have argument names that are the same as attribute names, unless the 'whee'/'.whee' prohibition were relaxed. :( But it's an intriguing thought, nonetheless. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 05:40 AM 7/5/2006 -0400, Scott Dial wrote: Guido van Rossum wrote: Would this also use ..num to refer to num in an outer scope two levels removed? I realize this was a wink, but it is a valid problem with the dot-proposal. Actually, it isn't. :) See below. def foo(n): def bar(n): def baz(): return .n So, which 'n' outer 'n' is being referenced? Notice that this is a made-up example. Existing Python scoping rules don't allow this! Thus your example is not a bug, it's a feature request. And I say we say no to adding this feature. ;-) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: By the way, an interesting thought for Py3K is that you could maybe use this syntax to do away with explicit 'self', if you consider the class' namespace to be part of a function's closure. Sorry, but now I am *definitely* -1. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/5/06, Michael Chermside [EMAIL PROTECTED] wrote: Guido writes: [discussion of how to fix the can't-bind-outer-scope-vars wart] I think we have to continue to search for a solution that extends the idea of global declarations. I've proposed extending its meaning to refer to the nearest outer scope where the variable is set; if there is no such scope it's an error. This will break a small number of program but probably not very many; still, it'll require a future statement or waiting until Python 3.0. The downside is that global is not a very intuitive word for this new meaning. I disagree with your last statement -- I think global _is_ a very intuitive word for this. As I understand it, in programming global has two meanings, closely intertwined. One is universal, same throughout the system. For instance, The singleton pattern is used to create a single, global instance of a type. The second meaning is the term global variable. This term developed (I believe) in languages that had only two scopes: local-to-current-function and global-to-entire-program. But the term global variable refers to any variable whose assignment is a side effect, regardless of whether that variable is global-to-entire-program, global-to-module, or even global-to-enclosing-function. I have even heard the term global variable (mis)used to refer to any kind of side effect. Anyhow, in Python only builtins is _really_ global -- even today's global keyword only refers to module scope. So I believe that it would be a very reasonable interpretation of global to mean not local, and implement as search enclosing scopes in order to find the binding. I really wish I could agree with you, because that would make the choice so much easier. However I still don't believe global has the stretchiness in its meaning that you claim it has. Have you ever heard a Python programmer talking about closures use the word global variable? Are there any other native speakers who side with Michael? -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Phillip Eby writes: I don't see a problem with requiring '.x' to be used for both reading and writing of outer-scope names; it just shouldn't be required for an outer-scope name that you don't rebind in the current scope. def counter(num): def inc(): .num += 1 return .num return inc I am reminded of Tim Peter's declaration in response to a similar proposal some time ago: Syntax should not look like grit on my monitor. (Sorry, no reference... but I swear it's word-for-word accurate because the quote burned itself into my memory.) -- Michael Chermside ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Phillip Eby writes: The big problem that comes to mind with that idea is that it makes it impossible to have argument names that are the same as attribute names, unless the 'whee'/'.whee' prohibition were relaxed. :( But it's an intriguing thought, nonetheless. My three-year-old has been working on that 'whee'/'.whee' prohibition, but he hasn't mastered it yet. Gotta-go-wash-another-load-of-underpants -lly yours, Michael Chermside ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
At 07:27 PM 7/5/2006 +0200, Guido van Rossum wrote: However I still don't believe global has the stretchiness in its meaning that you claim it has. Have you ever heard a Python programmer talking about closures use the word global variable? Are there any other native speakers who side with Michael? I don't, and am -1 on using global to mean outer. Of course, I also don't really care for using global to refer to a module level variable, or it being the only non-executable statement in Python, but these are very minor things and relatively easily explained to the programmers I've worked with. Using global to mean outer, on the other hand, would surely lead to much wailing and grinding of teeth in response to any attempt at rational explanation. :) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Marek Baczek Baczyński wrote: I suggest - as an assignment operator instead of := - it's used in OCaml and it looks *very* different, yet still makes sense. But assigning to an outer scope isn't *very* different, it's only slightly different. -- And now for something slightly different... Greg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Simon Percivall wrote: def foo(): def bar(): foo.x = 3 That already had a different meaning - it assigns to an attribute of the function object created by executing def foo(). -- Greg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
[EMAIL PROTECTED] wrote: By naming the function in which the binding is to occur you avoid problems of someone coming along and adding or deleting functions between the assignment (in baz) and the target of the assignment (x in foo) but then forgetting to increment or decrement the counters that refer to a fixed number of levels above the current function. But it doesn't do anything for the (I expect much more common) case of factoring out something in a function body and making it a nested function -- you'd still have to change the form of all the references to the name in that case. Better not to have a scheme that uses counters or scope names at all, I think. -- Greg ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On Wed, 5 Jul 2006, Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Using the classic nonsense example: def counter(num): def inc(): .num += 1 return .num return inc Would this also use ..num to refer to num in an outer scope two levels removed? I don't think there's any need for that. I see '.num' as just another way of saying num, but don't make a new binding. I agree with Guido that the best proposals so far are converging on the idea that it's more Pythonic to say don't make a new binding when a variable is used, than to declare this is the scope for this binding ahead of time. Of those there are two kinds: (a) State once (anywhere in a scope, but preferably at the beginning) that a variable is non-local. This is like the global keyword works now, and this category includes: - Change the meaning of 'global'. - Add a new keyword 'outer' or 'nonlocal', etc. (b) Indicate, when mentioning a variable, that the variable is non-local. This category includes: - Say 'global.x' or 'outer.x' instead of 'x'. - Say '.x' instead of 'x'. My favourite so far is to use a new keyword -- i think changing the meaning of 'global' would be misleading. '.x' is probably my next favourite, though i share Guido's concern about allowing both 'x' and '.x' to refer to the same thing. I see that 'outer' is used as an identifier in hmac.py in the standard library and also as a variable in test_set*.py. On the other hand 'nonlocal' does not appear anywhere in the standard library. Thus, 'nonlocal' is the best option that i've seen so far; it's less likely to break anything and it says exactly what it means. I can't think of a more accurate keyword. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
+1 on nonlocal. I think that the := operator is also in case (b), but as I don't like it I'm find with not mentioning it. :-) Could someone write a PEP for this? Doesn't have to be very long but I'd like it to summarize the main options proposed and discuss them, like I did for the switch PEP. It's a p3yk PEP. (We really need to move this to the py3k list...) --Guido On 7/6/06, Ka-Ping Yee [EMAIL PROTECTED] wrote: On Wed, 5 Jul 2006, Guido van Rossum wrote: On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: Using the classic nonsense example: def counter(num): def inc(): .num += 1 return .num return inc Would this also use ..num to refer to num in an outer scope two levels removed? I don't think there's any need for that. I see '.num' as just another way of saying num, but don't make a new binding. I agree with Guido that the best proposals so far are converging on the idea that it's more Pythonic to say don't make a new binding when a variable is used, than to declare this is the scope for this binding ahead of time. Of those there are two kinds: (a) State once (anywhere in a scope, but preferably at the beginning) that a variable is non-local. This is like the global keyword works now, and this category includes: - Change the meaning of 'global'. - Add a new keyword 'outer' or 'nonlocal', etc. (b) Indicate, when mentioning a variable, that the variable is non-local. This category includes: - Say 'global.x' or 'outer.x' instead of 'x'. - Say '.x' instead of 'x'. My favourite so far is to use a new keyword -- i think changing the meaning of 'global' would be misleading. '.x' is probably my next favourite, though i share Guido's concern about allowing both 'x' and '.x' to refer to the same thing. I see that 'outer' is used as an identifier in hmac.py in the standard library and also as a variable in test_set*.py. On the other hand 'nonlocal' does not appear anywhere in the standard library. Thus, 'nonlocal' is the best option that i've seen so far; it's less likely to break anything and it says exactly what it means. I can't think of a more accurate keyword. -- ?!ng -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Explicit Lexical Scoping (pre-PEP?)
This is sort of a re-do of an earlier proposal which seems to have gotten lost in the shuffle of the larger debate. I propose to create a new type of scoping rule, which I will call explicit lexical scoping, that will co-exist with the current implicit scoping rule that exists in Python today. Definitions: Implicit scoping is what we have now - a variable is defined within a scope implicitly by assignment. More specifically, when a name is assigned, the name is defined at the innermost function-level scope from where the assignment took place. Explicit scoping is where the programmer explicitly specifies which scope the variable should be defined in. Unlike implicit scoping, assignments to a named variable do not automatically redefine that variable within the current scope. Syntax: Borrowing from Perl, the keyword 'my' is used to declare an explicitly scoped variable: def f1(): my x = 1 def f2(): x = 2 # Does not create a new x In the above example, the statement 'my x = 1' declares that the scope of the variable 'x' is the outer function f1. Any assignment to x will modify the existing x, rather than creating a new definition. Note that the 'my' prefix can be combined with an assignment operation. It is anticipated that the 'my' prefix will be used quite frequently (and encouraged), so it makes sense to cut down on the number of statements by combining declaration and assignment. Explicitly scoped variables can also be declared at the module level: my x = 1 def f1(): x = 2 # Modifies the global X Declaring a module-level variable with an explicit scope eliminates the need for a 'global' statement for that variable. Nested Scopes: Each occurance of the keyword 'my' creates a new scope which hides any outer definitions of the name. So for example: my x = 1 def f1(): my x = 2 # This is a different 'x' than the global def f2(): x = 3 # This is the 'x' defined within f1() Interaction between explicit scoping and globals: The 'global' statement, when used with explicitly scoped variables, means exactly the same as it does with implicitly scoped variables: It allows access to the outermost scope, overriding any intermediate definitions in surrounding scopes: x = 1 def f1(): my x = 2 def f2(): global x x = 3 # This is the module-level 'x' Explicit scoping and code block structure: Implicitly scoped variables are always defined at the nearest enclosing function scope, even if they are created within a code block. It might be worth considering allowing explicitly scoped variables to be defined within other scopes. For example, we might choose to allow explicit scope declarations to be limited to the current suite: def f1(): for x in range(0,10): my y = x*x # A new definition of y for each iteration Note that this is a speculation only, and not a core part of the proposal (so please don't reject the proposal on this one point.) Formal definition: When a value is assigned to a local variable name, the rules for determining which scope the variable will be defined in are as follows: 1) Starting with the current (innermost) scope, examine all of the currently active scopes: 1a) If the current scope contains a 'global' statement for the given name, then set the result scope to the outermost (module-level) scope. 1b) If the current scope contains a 'my' statement for the given name, then set the result scope to the scope in which the 'my' statement occurred. 2) Otherwise, continue until we run out of scopes. If neither a 'global' or 'my' declaration was discovered, then use the innermost scope as the result scope. How is this different from 'outer'? The explicit scope proposal requires that the scope be specified at the place where the variable is *defined* as opposed to where it is *used*. This definition is inherited by all inner scopes. This allows a finer degree of control, for less typing, than the 'outer' proposal. With explicit scoping, there is no confusion as to which scope is being considered; And explicit scoping allows a single declaration of a variable to be shared by many different inner scopes, which would otherwise require a separate 'outer' statement for each one. Explicit scoping and static analysis: It should be easier to do static analysis of code with explicit scoping, since you always know what scope a variable is defined in (as opposed to implicit scoping, where a variable may switch from global to local as a result of an assignment.) Note that this implies that the creation of the scope does not occur at the time of the assignment, but rather at the time the function is entered. Thus: x = 1 def f1(): print x # Error, unassigned value my x = 2 In the above example, even though the 'my' statement occurs after the
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Talin wrote: This is sort of a re-do of an earlier proposal which seems to have gotten lost in the shuffle of the larger debate. I propose to create a new type of scoping rule, which I will call explicit lexical scoping, that will co-exist with the current implicit scoping rule that exists in Python today. Interesting. What if for-loops implicitally used my on the iteration variable? That would solve the binding problem we were discussing and make lambdas Do The Right Thing(TM) when used in loops. -- Giovanni Bajo ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Borrowing from Perl, the keyword 'my' is used to declare an explicitly scoped variable: def f1(): my x = 1 def f2(): x = 2 # Does not create a new x In the above example, the statement 'my x = 1' declares that the scope of the variable 'x' is the outer function f1. Any assignment to x will modify the existing x, rather than creating a new definition. -1, for this reason: def f() x = 2 # Does this create a local variable? Today, the answer is yes. Under this proposal, you can't answer the question without inspecting the entire context in which f is defined. For that reason, I would much rather have the first assignment in a block say explicitly whether it is intended to create a local variable: def f1(): x = 1 def f2(): global x x = 2# Does not create a new x This might even be abbreviated: def f1(): x = 1 def f2(): global x = 2 # Equivalent to the last example above ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
Please move this to the python-3000 list. Also please explain what problem you are solving before proposing a solution. I note that we are seeing quite a flurry of language change proposals. I have to recommend restraint; I *don't* want to turn the entire language upside down. That's not a comment on this particular proposal, but on the issue of too many proposals. From actual users of the language I get more complaints about the breakneck speed of Python's evolution than about the brokenness of the current language. --Guido On 7/4/06, Talin [EMAIL PROTECTED] wrote: This is sort of a re-do of an earlier proposal which seems to have gotten lost in the shuffle of the larger debate. I propose to create a new type of scoping rule, which I will call explicit lexical scoping, that will co-exist with the current implicit scoping rule that exists in Python today. Definitions: Implicit scoping is what we have now - a variable is defined within a scope implicitly by assignment. More specifically, when a name is assigned, the name is defined at the innermost function-level scope from where the assignment took place. Explicit scoping is where the programmer explicitly specifies which scope the variable should be defined in. Unlike implicit scoping, assignments to a named variable do not automatically redefine that variable within the current scope. Syntax: Borrowing from Perl, the keyword 'my' is used to declare an explicitly scoped variable: def f1(): my x = 1 def f2(): x = 2 # Does not create a new x In the above example, the statement 'my x = 1' declares that the scope of the variable 'x' is the outer function f1. Any assignment to x will modify the existing x, rather than creating a new definition. Note that the 'my' prefix can be combined with an assignment operation. It is anticipated that the 'my' prefix will be used quite frequently (and encouraged), so it makes sense to cut down on the number of statements by combining declaration and assignment. Explicitly scoped variables can also be declared at the module level: my x = 1 def f1(): x = 2 # Modifies the global X Declaring a module-level variable with an explicit scope eliminates the need for a 'global' statement for that variable. Nested Scopes: Each occurance of the keyword 'my' creates a new scope which hides any outer definitions of the name. So for example: my x = 1 def f1(): my x = 2 # This is a different 'x' than the global def f2(): x = 3 # This is the 'x' defined within f1() Interaction between explicit scoping and globals: The 'global' statement, when used with explicitly scoped variables, means exactly the same as it does with implicitly scoped variables: It allows access to the outermost scope, overriding any intermediate definitions in surrounding scopes: x = 1 def f1(): my x = 2 def f2(): global x x = 3 # This is the module-level 'x' Explicit scoping and code block structure: Implicitly scoped variables are always defined at the nearest enclosing function scope, even if they are created within a code block. It might be worth considering allowing explicitly scoped variables to be defined within other scopes. For example, we might choose to allow explicit scope declarations to be limited to the current suite: def f1(): for x in range(0,10): my y = x*x # A new definition of y for each iteration Note that this is a speculation only, and not a core part of the proposal (so please don't reject the proposal on this one point.) Formal definition: When a value is assigned to a local variable name, the rules for determining which scope the variable will be defined in are as follows: 1) Starting with the current (innermost) scope, examine all of the currently active scopes: 1a) If the current scope contains a 'global' statement for the given name, then set the result scope to the outermost (module-level) scope. 1b) If the current scope contains a 'my' statement for the given name, then set the result scope to the scope in which the 'my' statement occurred. 2) Otherwise, continue until we run out of scopes. If neither a 'global' or 'my' declaration was discovered, then use the innermost scope as the result scope. How is this different from 'outer'? The explicit scope proposal requires that the scope be specified at the place where the variable is *defined* as opposed to where it is *used*. This definition is inherited by all inner scopes. This allows a finer degree of control, for less typing, than the 'outer' proposal. With explicit scoping, there is no confusion as to which scope is being considered; And explicit scoping allows a single declaration of a variable to be shared by many different inner scopes, which would otherwise require a separate 'outer'
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/4/06, Talin [EMAIL PROTECTED] wrote: Guido van Rossum wrote: Also please explain what problem you are solving before proposing a solution. Actually, the problem I am trying to solve is the debate on the mailing list. That is, I listen to what people are asking for, and what disagreements they have, and then I try to provide a solution that resolves the debate. In this case, there was a lot of discussion about lexical scoping, and various people proposing solutions (such as redefining the behavior of 'global') that I thought were (a) problematic, and (b) not a lot of bang for the buck (i.e. the disruption vs. utility tradeoff was poor IMHO.) To be honest, I really have no stake in this proposal, and I don't intend to spend any time defending it other than to correct misperceptions - however, I offer it as a potential starting point for people who are interested in the whole lexical scoping issue. If someone feels that this proposal gives them what they want, then great - otherwise I'll drop it. Thanks; I appreciate the attempt. I just think that we're not quite ready for more proposals (and certainly not for radical ones). Instead, I'd like to go back to review the needs and desires first. I think the needs are actually pretty simple. Python currently doesn't allow assignment to variables in an outer non-global scope, and people have shown by their behavior that they cannot get used to this (otherwise the debate would have fizzled by now). There are two fundamentally different mechanisms seen in programming languages to control the binding of such variables. The most common approach is to require declaration of variables in the scope to which they belong. But Python doesn't do this, and I think it would be a shame if we had to start doing this now -- the objections against your proposal clearly show the problems if we try to mix this with Python's traditional assignment is declaration philosophy. The other approach is an extension of what Python already does for variables in the global scope. ABC did this too (the SHARE command, see http://homepages.cwi.nl/~steven/abc/qr.html#HOWTOs). I think we have to continue to search for a solution that extends the idea of global declarations. I've proposed extending its meaning to refer to the nearest outer scope where the variable is set; if there is no such scope it's an error. This will break a small number of program but probably not very many; still, it'll require a future statement or waiting until Python 3.0. The downside is that global is not a very intuitive word for this new meaning. (Maybe ABC's SHARE would have been better.) We could use a different keyword instead, e.g. 'outer'. I believe I've also seen proposals in the past that used a number to indicate how many scopes to go out; I don't like that at all. I don't see anything else that's attractive. The realistic options are: 1. do nothing 2. extend global's meaning 3. add outer keyword Personally I think I'd vote for (2) since it doesn't require a new keyword. But that's only a slight preference over the other two. Personally it's not a burning need; by the time you start feeling the need to modify variables in an outer scope you should probably consider refactoring using an explicit class to hold the state. But I used the same argument to keep the current form of nested scopes (can we say closures? But what exactly is the closure?) out of the door and I lost that argument. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
On 7/5/06, Phillip J. Eby [EMAIL PROTECTED] wrote: At 12:18 AM 7/5/2006 +0200, Guido van Rossum wrote: I don't see anything else that's attractive. The realistic options are: 1. do nothing 2. extend global's meaning 3. add outer keyword Did you also consider and reject: * Alternate binding operators (e.g. :=, .=, etc.) Brr. * Alternate spelling of outer names when binding (e.g. .x = whatever to bind an outer x) We looked at and rejected globals.x = whatever. I think the same reasoning applies here. If so, then these should probably be added to the rejected alternatives for Py3K so they don't get rehashed. Georgbot? -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com