On Sun, Mar 25, 2018 at 6:29 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Mon, Mar 26, 2018 at 12:24 PM, Guido van Rossum <guido@python.org> 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. :-)

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.)

It would still require carefully defining execution order in all cases, but we should probably do that anyway.

At some point we could introduce a "block" statement similar to Lua's do/end or C's blocks (also found in many other languages). But there's not really a lot of demand for this -- style guides justly frown upon functions so long that they would benefit much.

--Guido van Rossum (python.org/~guido)