[Python-Dev] (name := expression) doesn't fit the narrative of PEP 20

Tim Peters tim.peters at gmail.com
Wed Apr 25 17:55:43 EDT 2018


[Guido]
>> You don't seem to grasp the usability improvements this will give.
>> I hear you but at this point appeals to Python's "Zen" don't help you.

[Łukasz Langa <lukasz at langa.pl>]
> This reads dismissive to me. I did read the PEP and followed the discussion on
> python-dev. I referred to PEP 20 because it distills what's unique about the
> value proposition of Python. It's our shared vocabulary.
>
> Can you address the specific criticism I had? To paraphrase it without PEP 20
> jargon:

>  (name := expression) makes code less uniform.  It inserts more information
>   into a place that is already heavily packed with information (logic tests).

I'll take a crack at that.  It's not about "head arguments" at all.  I
sat out the first hundred messages about this on python-ideas, and
looked at code instead.  What I found had little to do with any of the
head (abstract) arguments passionately debated for the duration ;-)

In real life, I found a great many conditional tests that not only
weren't "heavily packed" with information, they were simply of the
form:

    NAME = expression
    if NAME:
        ... use NAME ...

That looks more like assembly language than Python ;-)  I saw no harm
at all, and a little gain, in

    if NAME := expression:
        ... use NAME ...

instead.  But even a little gain adds up when it happens so often.

Of course there have been better examples given of bigger gains.  But
in no case have the tests in those examples been "heavily packed with
information".  If they had been, I would have suggested instead
breaking the test clauses _out_ of the conditional statements, and
giving them names each on their own dedicated lines, with comments
explaining what the heck the _intents_ are, even at the cost of adding
an indentation level or two. Sometimes conditionals are _already_ "too
dense".  But more often they're very sparse.

This becomes a question of seasoned judgment.  For example, here's a
real loop summing a series expansion, until the new terms become so
small they make no difference to the running total (a common enough
pattern in code slinging floats or decimals):

        while True:
            old = total
            total += term
            if old == total:
                return total
            term *= mx2 / (i*(i+1))
            i += 2

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.

But neither do I need a compelling head argument for "why" to know
that in many other cases I find that the use of binding expressions
improves the code.  You shouldn't believe me even if I pretended to
have one and passionately argued for it.  But, by the same token, I'm
spectacularly unmoved by other peoples' head arguments.

For that reason, the messages that sway me are those showing real
code, or at least plausibly realistic code.  In the majority of those
so far, binding expressions would be a small-to-major win.


More information about the Python-Dev mailing list