
[Neal]
def reset_foo(): global foo = [] # declare as global and do assignment
[Alex]
Indeed, you can see 'global', in this case, as a kind of "operator keyword", modifying the scope of foo in an assignment statement.
I really have two separate peeves against global (not necessarily in order of importance, actually):
-- it's the wrong keyword, doesn't really _mean_ "global"
I haven't heard anyone else in this thread agree with you on that one. I certainly don't think it's of earth-shattering ugliness.
-- it's a "declarative statement", the only one in Python (ecch) (leading to weird uncertainty about where it can be placed)
I'd be happy to entertain proposals for reasonable restrictions on where 'global' can be placed. (Other placements would have to be deprecated at first.)
-- "side-effect" assignment to globals, such as in def, class &c statements, is quite tricky and error-prone, not useful
Agreed; nobody uses these, but again this can be fixed if we want to (again we'd have to start deprecating existing use first). Note that this is also currently allowed and probably shouldn't: def f(): global x for x in ...: ...
Well, OK, _three_ peeves... usual Spanish Inquisition issue...:-)
Your proposal is quite satisfactory wrt solving the second issue, from my viewpoint. It would still create a unique-in-Python construct, but not (IMHO) a problematic one.
Well, *every* construct is "unique in Python", isn't it? Because Python has only one of each construct, in line with the TOOWTDI zen. Or do you mean "not seen in other languages"? I'd disagree -- lots of languages have something similar, e.g. "int x = 5;" in C or "var x = 5" in JavaScript. IMO, "global x = 5" is sufficiently similar that it will require no time to learn.
As you point out, it _would_ be more concise than having to separately [a] say foo is global then [b] assign something. It would solve any uncertainty regarding placement of 'global', and syntactically impede using global variables in "rebinding as side-effect" cases such as def &c, so the third issue disappears.
The first issue, of course, is untouched:-). It can't be touched without choosing a different keyword, anyway.
So, with 2 resolutions out of 3, I do like your idea.
I don't think that Neal's proposal solves #3, unless 'global x = ...' becomes the *only* way. Also, I presume that the following: def f(): global x = 21 x *= 2 print x should continue to be value, and all three lines should reference the same variable. But #3 is moot IMO, it can be solved without mucking with global at all, by simply making the parser reject 'class X', 'def X', 'import X' and 'for X' when there's also a 'global X' in effect. Piece of cake.
However, I don't think we can get there from here. Guido has explained that the parser must be able to understand a statement that starts with 'global' without look-ahead; I don't know if it can keep accepting, for bw compat and with a warning, the old global xx while also accepting the new and improved global xx = 23
There is absolutely no problem recognizing this.
But perhaps it's not quite as hard as the "global.xx = 23" would be. I find Python's parser too murky & mysterious to feel sure.
If you can understand what code can be recognized by a pure recursive descent parser with one token lookahead and no backtracking, you can understand what Python's parser can handle.
Other side issues: if you rebind a module-level xx in half a dozen places in your function f, right now you only need ONE "global xx" somewhere in f (just about anywhere); with your proposal, you'd need to flag "global xx = 23" at each of the several assignments to that xx. Now, _that suits me just fine_: indeed, I LOVE the fact that a bare "xx = 23" is KNOWN to set a local, and you don't have to look all over the place for declarative statements that might affect its semantics
You may love this for assignments, but for *using* variables there is already no such comfort. Whether "print xx" prints a local or global variable depends on whether there's an assignment to xx anywhere in the same scope. So I don't think that is a very strong argument.
(hmmm, perhaps a 4th peeve vs global, but I see it as part and parcel of peeve #2:-). But globals-lovers might complain that it makes using globals a TAD less convenient. (Personally, I would not mind THAT at all, either: if as a result people use 10% fewer globals and replace them with arguments or classes etc, I think that will enhance their programs anyway;-).
So -- +1, even though we may need a different keyword to solve [a] the problem of getting there from here AND [b] my peeve #1 ...:-).
--Guido van Rossum (home page: http://www.python.org/~guido/)