[Steven D'Aprano <st...@pearwood.info>]
> Chris' PEP 572 started off with the concept that binding expressions
> would create a "sub-local" scope, below function locals. After some
> debate on Python-Ideas, Chris, Nick and Guido took the discussion off
> list and decided to drop the sub-local scope idea as confusing and hard
> to implement.

Enormously harder to implement than binding expressions, and the
latter (to my eyes) capture many high-value use cases "good enough".

I'm not concerned about "confusing".  "Sub-local" scopes are
ubiquitous in modern languages, and they're aimed at experienced
programmers.

It was also the case that nesting scopes _at all_ was very
controversial in Python's earliest years, and Guido resisted it
mightily (with my full support).  The only scopes at first were
function-local, module-global, and builtin, and while functions could
_textually_ nest, they had no access to enclosing local scopes.  Cute:
 to write a recursive nested function, you needed to pass it its own
name (because its own name isn't in its _own_ local scope, but in the
local scope of the function that contains it).

Adding nested local scopes was also "confusing" at the time, and
indeed made the scoping rules far harder to explain to newbies, and
complicated the implementation.  Then again, experienced programmers
overwhelmingly (unanimously?) welcomed the change after it was done.

Since then, Python has gone down a pretty bizarre path, inventing
sublocal scopes on an ad hoc basis by "pure magic" when their absence
in some specific context seemed just too unbearable to live with
(e.g., in comprehensions).  So we already have sublocal scopes, but in
no explicit form that can be either exploited or explained.


> But the biggest problem is that this re-introduces exactly the same
> awful C mistake that := was chosen to avoid. Which of the following two
> contains the typo?
>
>     local(spam=expression, eggs=expression, cheese = spam+eggs)
>
>     local(spam=expression, eggs=expression, cheese == spam+eggs)

Neither :-)  I don't expect that to be a real problem.  In C I'm
_thinking_ "if a equals b" and type "if (a=b)" by mistake in haste.
In a "local" I'm _ thinking_ "I want to create these names with these
values" in the former case, and in the latter case also "and I want to
to test whether cheese equals spam + eggs".  But having already typed
"=" to mean "binding" twice in the same line, "but the third time I
type it it will mean equality instead" just doesn't seem likely.

The original C mistake is exceedingly unlikely on the face of it:  if
what I'm thinking is "if a equals b", or "while a equals b", I'm not
going to use "local()" _at all_.  Forcing the programmer to be
explicit about that they're trying to create a new scope limits the
only possible confusions to cases where they _are_ going out of their
way to use a "local()" construct, in which case binding behavior is
very much at the top of their mind.  Plain old "if a=b" remains a
SyntaxError regardless.

Still, if people are scared of that, a variation of Yury's alternative
avoids it:  the last "argument" must be an expression (not a binding).
In that case your first line above is a compile-time error.

I didn't like that because I really dislike the textual redundancy in the common

    if local(matchobject=re.match(regexp, line), matchobject):

compared to

    if local(matchobject=re.match(regexp, line)):

But I could compromise ;-)

- There must be at least one argument.
- The first argument must be a binding.
- All but the last argument must also be bindings.
- If there's more than one argument, the last argument must be an expression.

Then your first line above is a compile-time error, the common "just
name a result and test its truthiness" doesn't require repetition, and
"local(a==b)" is also a compile-time error.


> I have other objections, but I'll leave them for now, since I think
> these two alone are fatal.

I don't.


> Once you drop those two flaws, you're basically left with PEP 572 :-)

Which is fine by me, but do realize that since PEP 572 dropped any
notion of sublocal scopes, that recurring issue remains wholly
unaddressed regardless.
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to