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/