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

Steven D'Aprano steve at pearwood.info
Fri Apr 27 01:38:37 EDT 2018


On Thu, Apr 26, 2018 at 08:48:12AM -0700, Łukasz Langa wrote:
> 
> > On Apr 25, 2018, at 11:10 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> > Criticising binding- 
> > expressions for that reason, especially implying that we must always use 
> > parens, is simply FUD.
> 
> The PEP has more examples with parentheses than without.

Yes? Parens aren't mandatory, and my point that other operators also 
sometimes needs parens still holds.


> >> As soon as we have to wrap a part of an expression in parentheses, 
> >> parsing the entire thing becomes more complex.
> > 
> > Unless it becomes less complex to read and understand.
> 
> You're ignoring the context of the discussion. The new parentheses are 
> there because there's a new assignment there. That's more complex.

I'm not ignoring the context of the discussion. I'm comparing binding- 
expression with and without parens. That's what I thought you were 
doing.

If that wasn't your intended meaning, then I apologise but please 
understand why I answered the way I did.

I still stand by my argument: parens are not always needed, and even 
when they are not needed, adding them can sometimes make things 
*easier* and *less complex* to read.


[...]
> If you think demonstrating cases where the end result won't be an 
> improvement is picking at straws, then maybe the improvement of PEP 
> 572 is as well.

Any feature can have cases where the end result is worse than not using 
the feature. That *alone* isn't a strong argument against a feature.

Do you have much existing code using binding expressions? Of course not. 
Will you be adding them to code that already exists? Probably not -- you 
can't do so until you are using 3.8 at minimum, and if your code needs 
to be backwards compatible, you can't use it until you've dropped 
support for 3.7 and older. That might not be for five or ten years.

So it is likely that for most people only new code will use this 
feature. It is not reasonable to say that if I have existing code like 
this:

    spam = expression
    if long_condition_that_takes_up_most_of_the_line == spam or spam:
        ...

that I'm going to immediately change it to a one-liner:

    if long_condition_that_takes_up_most_of_the_line == (spam := expression) or spam:
        ...

and push it over the maximum line width. With or without parentheses. 
Why would I do something so silly? Using binding expressions isn't 
mandatory and most coders don't intentionally do things that make their 
code worse.

And if I wouldn't change existing code and push it over the limit, why 
would I write new code that does it? Especially when there are much 
better alternatives:

    if (long_condition_that_takes_up_most_of_the_line 
            == (spam:=expression)
            or spam):
        ...


We have a history of adding features that can be abused, but aren't. 
People hardly ever abuse list comps with overly long and complex 
multiple-loop comprehensions:

    [... for a in sequence for b in something for c in another for d in something_else]

I'm sure we've all seen one or two of those. But it doesn't happen 
enough to matter. Same with if...elif...else chains. People didn't 
immediately run out and replace every single if chain into nested 
ternary if expressions, pushing their lines out to beyond the maximum 
line width:

    expression if condition else (expression if condition else (expression if condition else (expression if condition else expression)))

Real people don't abuse comprehensions or ternary if enough for us to 
regret adding them to the language. I'm sure that they won't abuse this 
feature either. The Python community simply doesn't have the culture of 
abusing syntax in this way and writing overly dense one-liners, and I 
don't think it is reasonable to say this feature will tip the balance.

It is reasonable to say that *some* code will be made worse by this, 
because there's always *someone* who will abuse syntax. There are those 
who insist on writing list comprehensions for their side-effects:

    # return and throw away a list of Nones
    [print(item) for item in bunch_of_stuff]

but I don't think this happens enough to make us regret adding 
comprehensions to the language.


-- 
Steve


More information about the Python-Dev mailing list