[Python-ideas] PEP 572: Statement-Local Name Bindings, take three!

Guido van Rossum guido at python.org
Mon Mar 26 00:34:13 EDT 2018


On Sun, Mar 25, 2018 at 6:29 PM, Chris Angelico <rosuav at gmail.com> wrote:

> On Mon, Mar 26, 2018 at 12:24 PM, Guido van Rossum <guido at 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)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180325/2351e388/attachment.html>


More information about the Python-ideas mailing list