Hello,

On Sat, 28 Nov 2020 18:59:14 -0800
Guido van Rossum <gu...@python.org> wrote:

> I'm definitely being nerd-sniped here, so take this with a grain of
> salt.
> 
> The reason why Python currently doesn't have block scopes is the rule
> that assignment creates or updates a variable in the closest scope.
> This rule has taken Python far, because it means you can create a
> local variable by assigning to it without having to declare it.

And everybody loves Python for that. Nothing beats Python in being able
to take a 15-line algorithm in pseudocode, and write it in a way that it
still looks like a pseudocode but also actually runs.

But there're also 100-line and 200-line algorithms. And Python isn't
used just as a "pseudocode", but as a real implementation language for
software systems of different scales. And such usage over long time,
identified some, well, weaknesses. Some of them were addressed, but
arguably, in somewhat adhoc ways. And now there's an idea that maybe
it's time to address even wider scope of issues in a more general way.

> If we wanted to introduce something similar to C's block scopes,
> regardless of syntax, we'd have to answer the question where local
> variables will be declared.

Perhaps, we can start with saying "there won't be any breakages to
already existing scoping rules" (well, maybe rough-edge cleanups for
cases where adhoc workarounds were already applied).

> Suppose we had the (crummy) syntax
> 
> block var1 = exp1, var2 = exp2, ...:
>     <statements>
> 
> as the moral equivalent to C's
> 
> {
>     int var1 = exp1, var2 = exp2, ...;
>     <statements>
> }
> 
> then we'd still have to decide what should happen to assignments to
> variables *other* than var1, var2, etc. 

Simple answer: nothing. They will work as before.

> Consider
> 
> def f(x):
>     block a = 1:
>         x = a  # Is this local to the block or to the function?
>     return x
> 
> print(f(0))  # 0 or 1?
> 
> IMO, if 'x = a' were to create a new variable in the block, I think
> that would be confusing.

Not just "confusing", it would break backward compatibility. So, no go.

> It would also beg the question why we bother
> to adorn the block with variable declarations.

Indeed! So, we would take hint from existing Python variable
declarations, like "global" and "nonlocal", and would write it like
(let's imagine for a moment that we use "let" to introduce block-local
*mutable* variables):

def f(x):
    if 1:  # We can bikeshed how to make this more "beautiful" later. 
        let a = 1
        x = a  # Is this local to the block or to the function?
    return x

> There are other good reasons why any variable *not* explicitly
> declared as being part of a block should have function scope:

Backward compatibility is at the top of them, I'm sure.

> otherwise it would be impossible for code in a block to have a side
> effect to be consumed by the code outside the block. That could be
> addressed by using nonlocal, but at that point we might as well use a
> nested class statement (at least that gives us a way to get the
> locals out, as attributes of said class). Certainly it would be a
> shame if we added a block scope concept and we couldn't upgrade the
> for-loop to make use of it, optionally (like you can do in C with
> "for (int i = 0; i < n; i++) { ... }"). And a for-loop that can't set
> other variables that survive the loop seems crippled.
> 
> So maybe we should go with Paul's original gut feelings and introduce
> 
> let var1 = exp1, var2 = exp2, ...:
>     <statements>
> 
> with the semantics that it doesn't really create a fully-fledged new
> scope but defines scoped constants.

... except not constants, by *mutable* variables, ("const" would
introduce constants). And making it a suite-starting statement also
seems like bowing too much at the side of the functional languages (I
mean, typical syntax used for let's in them). "let", "const", are really
look similar to "global" and "const", except that they allow an
assignment to follow. (It's debatable whether multiple vars per one
"let" should be allowed.)

> It then would make sense to add some other syntax extensions like
> 
> for let i in ...:
>     <statements>

for const i in ...:

> 
> (makes i local to the loop, giving it the semantics needed by
> closures as well) and
> 
> with contextmanager() as let x:
>     <statements>

Likely also const.

> Clearly we need to bikeshed more about the syntax.
> 
> We could then declare that comprehensions implicitly use 'for
> let ...'. If we were to drive this through quickly enough we could
> even make it apply to pattern matching captures. (Or maybe pattern
> matching could get these semantics anyway.)
> 
> My bus is here, so that's it,

Thanks!

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


-- 
Best regards,
 Paul                          mailto:pmis...@gmail.com
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/GC3ZGMTVWYKMGVM76BHEVMTZ2IN5YIBR/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to