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

Tim Peters tim.peters at gmail.com
Thu Apr 26 16:33:24 EDT 2018


[Tim]
>> So, to match your sarcasm, here's mine:  try using a feature for what
>> it's good at instead of for what it's bad at ;-)

[Lukasz Langa <lukasz at langa.pl>]
> Yes, this is the fundamental wisdom.  Judging which is which is left as an
> exercise to the programmer.
>
> With this, I'm leaving the discussion.  With Guido and you on board for PEP
> 572, I feel that Chris' streak is indeed about to break.

I still expect it could go either way, but do wish people didn't
believe it will be a major loss if "the other side wins".  I'll be
fine regardless - and so will everyone else.  Guido rarely makes
language design mistakes.  In this case he's seeing serious opposition
from several core developers, and you shouldn't believe either that he
just dismisses that.


 [Łukasz Langa]
>>> Well, you have an entire code style built around this feature called Yoda
>>> conditions. You teach people on Day 1 to never ever confuse == with =. Some
>>> compilers even warn about this because so many people did it wrong.

>> Sorry, I couldn't follow that.

Part of the problem here is that I had never seen "Yoda conditions"
before, and had no idea what it meant.  Some later Googling suggests
it's "a thing" youngsters say at times ;-)


> You implied that newbies don't have to even know about assignments in
> expressions.  I wanted to demonstrate that this isn't really the case because
> mistaking `=` for `==` is a relatively common occurence for newbies.  If you
> want to argue that it isn't, I'd like to point out that the WordPress code
> style *requires* Yoda conditions because it was enough of a hindrance.  ESLint
> (a JavaScript linter) also has a warning about assignment in a conditional.

What does that have to do with Python?  If they try to use "=" in an
expression now, they get a SyntaxError.  The PEP doesn't change
anything about that.  Indeed, that's why it uses ":=" instead.  I have
experience in other languages with embedded assignments that also use
":=", and it's _never_ the case that people type ":=" when they intend
"equality test" in those.  The horrid "I typed = when I meant =="
mistakes are unique to languages that mindlessly copied C.  The
mistakes aren't primarily due to embedded assignments, they're due to
that even highly experienced programmers sometimes type "=" when
they're _thinking_ "equals".  Nobody types ":=" when they're thinking
"equals".


> ...
> What you're saying is true.  But for it to be true, newbies *have to* learn the
> distinction, and the fact that yes, sometimes the programmer indeed meant to
> put a single `=` sign in the conditional.

Again, the PEP is about Python:  a single "=" in a conditional is, and
will remain, a SyntaxError.  So nobody can sanely intend to put a
single "=" in a condition _in Python_ unless they're writing a test
intending to provoke a syntax error.


> That's why we'll end up with the Pascal assignment operator.

":=" is already in the PEP.


>  And that *is* a thing that you will have to explain to newbies when they encounter
> it for the first time.

Sure.  That doesn't frighten me, though.  It's easy to explain what it
does - although it may be hard to explain when it's _desirable_ to use
it.


> Sadly, googling for a colon followed by an equal sign isn't trivial if you don't
> know what you're looking for.

To judge from Stackoverflow volume, the single most misunderstood of
all Python operators - by far - is "is" - try Googling for that ;-)
In far second and third places are "and" and "or", for which searches
are also useless.

Regardless, I'm not concerned about one-time tiny learning curves.
Don't know what ":=" means already?  Ask someone.  If you know what
"=" means, you're already close to done.  Given that you already
understand what "binding a name" means, ":=" may well be the simplest
of all Python's operators (there's no computation _to_ be understood,
and no possibility either of a dunder method changing its meaning
depending on operand type(s)).


>>> Well, you can also use it as a statement. But don't!

>> Why not?  _Every_ expression in Python can be used as a statement.
>> Nothing forbids it, and that's even (very!) useful at an interactive
>> prompt.

> Because it suggests different intent, because it's limited, because it's slower
> at runtime, and because PEP 572 says so itself.

I didn't say you're _required_ to use it as a statement.  Regardless
of what PEPs say, people will do what they find most useful.  I trust
people to figure this out quickly for themselves.


>> At this point I think you must have a lower opinion of Python
>> programmers than I have ;-)  If adding even a dozen characters to a
>> line makes it exceed a reasonable line-length guide, the code was
>> almost certainly too confusingly dense to begin with.

> Around 5% of if and elif statements in the standard library don't fit a single
> line *as is*.  Sure, that's a low percentage but that's over 1,000 statements.
> If you're putting an `if` statement in a method, you are already starting out
> with 71 characters left on the line.  Four of those are going to be taken by
> "if", a space, and the colon.  Adding a parenthesized assignment expression
> takes at least 10% of that available space.

Confirming that you do have a lower opinion of them ;-)  Are you
picturing people stampeding to introduce ":=" in every place they
possibly could?  I may be wrong, but I don't expect that at all.  I
expect a vast majority of uses in real life will replace:

    name = expression
    if name:

by

    if name := expression:

and

    while True:
        name = expression
         if name comparison expression2:
            break

by

    while (name := expression) inverted_comparison expression2:

_provided that_ the latter spelling doesn't make the line
uncomfortably long.  In all the code of mine I've seen a good use for
it, there's a whole lot of empty horizontal screen space to spare,
even after recoding.  In places where I already had "long lines", I
didn't even check to see whether a binding operation could be used too
- why would I?  I don't feel _compelled_ to use it - I'm only looking
to reduce redundancy where it's an obvious win.


> The silver lining for me is that this makes the environment riper for
> auto-formatting.

See?  It's win-win for you too no matter how this turns out ;-)


More information about the Python-Dev mailing list