On Mon, Mar 26, 2018 at 3:34 PM, Guido van Rossum
On Sun, Mar 25, 2018 at 6:29 PM, Chris Angelico
wrote: On Mon, Mar 26, 2018 at 12:24 PM, Guido van Rossum
wrote: The scope question is far from easy though. I find it particularly grating that an inline assignment occurs in an 'if' statement, its scope is the entire body of the 'if'. If that body is two pages long, by the end of it the reader (or even the writer!) may well have lost track of where it was defined and may be confused by the consequence past the end of the body.
I think this one can be given to style guides. The useful situations (eg regex match capturing) are sufficiently valuable that the less-useful ones can just come along for the ride, just like "x = lambda: ..." is perfectly valid even though "def" would be preferable.
Not so fast. There's a perfectly reasonable alternative to sublocal scopes -- just let it assign to a local variable in the containing scope. That's the same as what Python does for for-loop variables. Note that for comprehensions it still happens to do the right thing (assuming we interpret the comprehension's private local scope to be the containing scope).
This alternative has significant advantages in my view -- it doesn't require a whole new runtime mechanism to implement it (in CPython you can just generate bytecode to store and load locals), and it doesn't require a new section in the documentation to explain the new type of variable scope. Also it would make Steven happy. :-)
I'm still liking the sublocal system, but making assignment expressions capable of standing plausibly without them is a Good Thing.
Perhaps we could even remove the requirement to parenthesize the new form of assignment, so we could say that at the statement level "<var> = <expr>" and "<var> := <expr>" just mean the same thing, or "=" is a shorthand for ":=", or whatever. In most cases it still makes sense to parenthesize it, since the := operator should have the same priority as the regular assignment operator, which means that "if x := f() and x != 42:" is broken and should be written as "if (x := f()) and x != 42:". But that could be a style guide issue. (Also note that I'm not proposing to add "+:=" etc., even though in C that's supported.)
That's about where I was thinking of putting it; "test" gets defined potentially as "NAME := test". It has to right-associate. At the moment, I'm going to be restricting it to simple names only, so you can't say "x[1] := 2". That may be changed later. ChrisA