On Wed, Apr 25, 2018 at 3:15 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
On 04/25/2018 02:55 PM, Tim Peters wrote:
To my eyes, this is genuinely harder to follow, despite its relative brevity:

         while total != (total := total + term):
             term *= mx2 / (i*(i+1))
             i += 2
         return total

So I wouldn't use binding expressions in that case.  I don't have a
compelling head argument for _why_ I find the latter spelling harder
to follow, but I don't need a theory to know that I in fact do.

I know why I do:  I see "while total != total" and my gears start stripping.  On the other hand,

  while total != (total + term as total):
     ...

I find still intelligible.  (Yes, I know "as" is dead, just wanted to throw that out there.)

The problem with either variant is that they hinge on subtle left-to-right evaluation rules. Python tries to promise left-to-right evaluation "except when it doesn't apply", e.g. in assignments the RHS is typically evaluated before subexpressions in the LHS: a[f()] = g() calls g() before f().

The example is supposed to load the left operand to != on the stack before loading the right operand, but the rule that says the left operand is evaluated before the right operand is much weaker than other evaluation order rules (like the rule stating that the arguments are evaluated before the function is called -- and before you laugh, in Algol-60 that wasn't always the case).

This argument applies regardless of which syntactic form you use, and no matter what we choose, the PEP will have to clarify evaluation order in more cases than the current reference manual. (IIRC Nathaniel brought this up.)
 
--
--Guido van Rossum (python.org/~guido)