Incremental operations don't require local scope
Acton Version
0.26.0
Steps to Reproduce and Observed Behavior
The following code is accepted by the compiler
def closure():
counter = 0
def inner():
counter += 1
while the presumably equivalent variant
def closure():
counter = 0
def inner():
counter = counter + 1
results in the error Name counter is reserved but not yet defined.
Expected Behavior
The compilation error must be the correct outcome even for the first variant, if we are to respect Python's scoping rules.
In other words: the compiler must assert that an incremental operation refers to a variable of the current scope before it proceeds with its rewrites.
If we're maintaining that reassignment (which is separate from mutation) of an outer variable is not allowed, then this is also wrong:
def closure():
f = ["here"]
def do():
print("do: {str(f)}")
def inner():
f = ["there"]
do()
inner()
Outputs do: ["there"]
Indeed! But now for a very different reason. This code gets an incorrect treatment in the lambda-lifter, where inner becomes parameterized on f just because do is -- the compiler doesn't detect that it accidentally captures another f along the way!
Tricky! But I'll make sure this is fixed along with the first bug.