On Thu, Nov 26, 2020 at 02:11:10PM +0300, Paul Sokolovsky wrote:
Using "let" will then give natural way to introduce proper block-level lexical scoping in Python:
Why would we want to do that?
Block-level scoping is too much of a good thing. The right level of scoping is the function, not the block.
(I'm willing to accept at least one exception to this, comprehensions.)
Block scoping adds complexity to the implementation *and* the semantics of code. Block scoping allows shadowing within a function. Some C-derived languages, such as Java and C#, considered that a big enough mistake that they corrected it by requiring variables within a block to be distinct from the variables outside of the block, which is conceptually weird.
The point of scoping is that variables in one scope should be independent of those in another scope, yet here we have this action at a distance where names in one scope can prevent you from using the same name in a different scope.
Python does have one example of a pseudo-block scope: the treatment of the except variable:
try: ... except Exception as err: ...
Effectively, "err" is treated as a "let" variable with a pseudo-block scope, limiting it to the except block. This is necessary, but an annoyance. I have come across many people suprised and annoyed that err is not available outside of the block.
(Fortunately, it is rare for folks to need access to the err variable outside of the block, otherwise the annoyance factor would be much greater.)
Block scoping adds semantic and implementation complexity and annoyance, while giving very little benefit. No thank you.
def foo(): let x = 1 if bar: let x = 2 ... # x is 1 again here
Is there a shortage of variable names that you have to reuse the same name "x" for two distinct variables?
I know that "naming things" is classically one of the hard problems of computer science, but this is taking things to an extreme.