On 4/5/2021 1:53 PM, Chris Angelico wrote:
On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy <tjre...@udel.edu> wrote:
*While 'a and not a' == False in logic, in Python it might raise
NameError.  But that would still mean that it is never True, making
'yield 0' still unreachable.

When I wrote that, I knew I might be missing something else.

And even just the lookup can have side effects, if your code is
pathologically stupid.

Or pathologically clever.

class Wat(dict):
...     def __missing__(self, key):
...             global count
...             count -= 1
...             return count

'__missing__' is new since I learned Python. I barely took note of its addition and have never used it. Thanks for the example of what it can do. One could also make it randomly return True or False.

count = 2
eval("print(a and not a)", Wat(print=print))
True

So Python can't afford to treat this as dead code.

This gets to the point that logic and math are usually atemporal or at least static (as in a frozen snapshot), while computing is dynamic. In algebra, the canon is that all instances of a variable are replaced by the same value.

Python *could* do the same for expresssions: load 'a' (in this case) once into a register or stack slot and use that value consistently throughout the expression. Replacing the eval with the following exec has the same effect.

exec("tem=a; print(tem and not tem)", Wat(print=print))
# print False

In this example, one could disable the binding with __setitem__ (resulting in printing 0), but python code cannot disable internal register or stack assignments.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to