unintuitive for-loop behavior

Steve D'Aprano steve+python at pearwood.info
Sun Oct 2 21:41:07 EDT 2016


On Sun, 2 Oct 2016 05:35 pm, Jussi Piitulainen wrote:

[...]
>> I'm sorry, I don't understand what you mean by "Python semantics" versus
>> "a translation". A translation of what? In what way is it "magical
>> semantics"? I see nothing magical in your code: it is Python code.
> 
> "Python semantics" is the semantics that Python actually uses when it
> updated the variables of a for-loop. I would like to call it "assignment
> semantics".
> 
> The second function is an executable translation of the first function
> under a different semantics. I would like to call it "binding semantics"
> to distinguish it from "assignment semantics", but that doesn't work
> when people insist that "binding" and "assignment" are the same thing in
> Python, so I called it "magical semantics" instead.

Why shouldn't people say that binding and assignment are the same thing in
Python? What's the difference?



[...]
>> Of course, it is complex, complicated, convoluted, obfuscated, hard to
>> understand, non-idiomatic Python code, but there's nothing magical in
>> it (unless you count nonlocal as magic). And it does nothing that
>> can't be done more simply: just change the tabulate inner loop
>> variable to a different name.
> 
> It was stated, in this thread, that it would have been impossible to
> make Python for-loops behave the way the corresponding Python code in my
> translations of the two nested for-loops behaves. I thought it would be
> a good idea to *show* how the "impossible" thing can be done.

I don't recall ever using the word "impossible", or seeing anyone else use
it. Obviously nothing is *literally* impossible unless it breaks the laws
of physics or requires more energy than available in the entire universe.

It goes without saying that if the Python core developers decide to change
the semantics of Python, add new features and functionality, add new
syntax, etc then such things are possible. They might be easy or they might
be hard -- in some cases *very* hard, requiring the Python VM to be rebuilt
from the ground up. But possible.

One should be careful about using the term "impossible", as well as taking
it literally.


> I could have just posted that yes, it *could* be done, there's nothing
> so special about variables and scope in Python. But I pretty much know
> that the response to *that* would have been yet another round of "You
> don't understand that Python variables are different, they are not boxes
> in fixes locations but name bindings, and no, it cannot be done."

I'm glad you know so much about what we would say before we say it.


>> def fabulate2(m, n):
>>     # The simple, Pythonic, non-complicated way.
>>     for i in range(m):
>>         print(i, end = ': ')
>>         c = 0
>>         for j in range(n):
>>             print(j, end = ', ' if j + 1 < n else ' : ')
>>             c += 1
>>         print(i, c)
> 
> It misses only the point of the exercise.

Perhaps that's because your point wasn't clear.


>>> A summary of sorts: it's possible to demonstrate the scope difference in
>>> Python code, with no box in sight; boxes are irrelevant; the relevant
>>> issue is what function and when the loop variable is associated with,
>>> explicitly or implicitly.
>>
>> I don't know what "scope difference" you think you are demonstrating.
>> tabulate() has a single scope, fabulate() has multiple scopes because it
>> has inner functions that take i as argument, making them local to the
>> inner functions. Um, yeah, of course they are different. They're
>> different because you've written them differently. What's your point?
> 
> The scope difference is the topic of this thread.
> 
> My point is that the for-loops could be translated/compiled/expanded
> into the lower-level code so that the loop variables would be in their
> own scopes.

Well why didn't you say so?

Perhaps I missed it the first time, but the point of the exercise would have
been so much more clear if only you had introduced it was an explanation
like:

"Here is a proof of concept that shows that Python could give for loops
their own scope. If this Python code [nested for-loops] were translated
mechanically by the compiler [nested while loops with iterators] then each
loop would have their own scope."


And you are absolutely right: boxes are irrelevant. I think that boxes only
came into this with Greg's argument that there's a difference
between "creating a new binding" versus "updating an existing one".


> The code might not seem so obfuscated to you if you thought of it not as
> source code but as compiled code. Except it's still Python. What word
> should I use instead of "translation"? Would "transformation" be
> understood?

That might have helped.





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list