unintuitive for-loop behavior

Chris Angelico rosuav at gmail.com
Sat Oct 1 03:41:26 EDT 2016


On Sat, Oct 1, 2016 at 5:06 PM, Steve D'Aprano
<steve+python at pearwood.info> wrote:
> Earlier, I wrote:
>
>> On Sat, 1 Oct 2016 10:46 am, Gregory Ewing wrote:
> [...]
>>> Whenever there's binding going on, it's necessary to decide
>>> whether it should be creating a new binding or updating an
>>> existing one.
>>
>> Right.
>
> I changed my mind -- I don't think that's correct.
>
> I think Greg's suggestion only makes sense for languages where variables are
> boxes with fixed locations, like C or Pascal. In that case, the difference
> between creating a new binding and updating a new one is *possibly*
> meaningful:
>
> # create a new binding
> x: address 1234 ----> [  box contains 999 ]
> x: address 5678 ----> [  a different box, containing 888 ]
>
> What happens to the old x? I have no idea, but the new x is a different box.
> Maybe the old box remains there, for any existing code that refers to the
> address of (old) x. Maybe the compiler is smart enough to add address 1234
> to the free list of addresses ready to be used for the next variable. Maybe
> its just lost and unavailable until this function exists.
>
> # update an existing binding
> x: address 1234 ----> [  box contains 999 ]
> x: address 1234 ----> [  same box, now contains 888 ]
>
>
> That's the normal behaviour of languages like C and Pascal. But its distinct
> from the previous, hypothetical behaviour.
>
> But Python doesn't work that way! Variables aren't modelled by boxes in
> fixed locations, and there is no difference between "create a new binding"
> and "update an existing one". They are indistinguishable. In both
> cases, 'x' is a key in a namespace dict, which is associated with a value.
> ...
> In a language like Python, the only distinction we can make between name
> bindings is, which namespace is the binding in? In other words, what is the
> current block of code's scope?

Yes, this is true; however, it's not difficult to create subscopes. I
put together a POC patch a while ago to make 'with' blocks able to put
their capture names into a separate subscope, transparently. I don't
think it's what Python wants, but it would be reasonably coherent
semantically ("with expr as name:" puts name, and name alone, into a
subscope - any other assignments are not), and wasn't difficult to
implement in CPython.

ChrisA



More information about the Python-list mailing list