
On Sun, 20 Aug 2023 at 09:28, Celelibi <celelibi@gmail.com> wrote:
Just as a reminder of C/C++: {pre,post}-{inc,dec}rementations bring their lot of issues with the language. Mostly the infamous *undefined behavors*. If you've done some C or C++ this very expression might send shivers down your spine.
The ONLY reason that this is undefined is to allow different compilers to optimize differently. Python does not need to hyper-optimize and could easily give this a clear definition.
Assuming a = 0, what's the value of a after: a = a++ ? What's the value of the expression (a++) + (++a) ? What values are passed to the function with: f(a, a++, a) ?
I am not sure these would be welcome in python. And allowing such syntax wouldn't feel really pythonic.
It would be trivially easy for the language to simply pick a definition. For example, here's a consistent evaluation pattern for all of them: 1) a = a++ LOAD a INCREMENT a STORE a Result: a has not changed 2) (a++) + (++a) LOAD a INCREMENT a INCREMENT a LOAD a BINARY_ADD Result: a gets incremented twice, and the final sum is equal to 2a+1 (for the original a). 3) f(a, a++, a) LOAD f LOAD a LOAD a INCREMENT a LOAD a FUNCTION_CALL 3 args Result: f(a, a, a+1) and a ends up incremented once. This is using a pseudo-bytecode similar to CPython's, with a new operation "INCREMENT" that can be considered to be equivalent to "a += 1" (which otherwise can't be inserted in the middle of an expression).
The worst part is not that the evaluation order is not always defined. It's that even if it were, most people wouldn't remember the rules since they're not obvious from the syntax. I'm not even sure most C programmers know what a "sequence point" is.
It hardly matters, because again, it's only because C needs the freedom to hyper-optimize. Python doesn't. Python can simply define that the increment happens immediately.
Some of the backlash about the walrus operator was precisely that it makes the order of evaluation much more important to know in order to understand a program. Assuming a = 0, what does this do: print(a, (a := a + 1), a) ?
Python evaluates left-to-right. This is a language guarantee. It will print out "0 1 1".
At least python makes it defined and obvious *when* the side effect occurs... As long as you know that expressions are evaluation left to right.
Exactly. I don't think Python needs pre-increment or post-increment, since their best value is in situations that can be handled differently (example: an array with its index or denoter can be stepped with "arr[d++]", but in Python, you could take its iterator and step it with "next(it)", with no great cost other than that you can't implement Star Wars merge sort using "arr1[d1++]" and "arr2[d2++]"). If you really DO need a post-incremented value, it wouldn't be too hard to have a "moving box" class: class Box: def __init__(self, value): self.value = value def next(self): ret = self.value self.value += 1 return ret Sure, it's not as clean, but the bar for syntax is high and the value here doesn't really reach that. But it wouldn't be undefined or underdefined. ChrisA