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

Wes Turner wes.turner at gmail.com
Fri Apr 27 06:18:36 EDT 2018


So, the style guidelines for this new feature -- and also ternary
expressions and comprehension -- would need to mention that:

- debuggers have no idea what to do with all of this on one line
- left-to-right doesn't apply to comprehensions

  results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]

- left-to-right doesn't apply to ternary expressions

  if (y := func(x)) if (x := 3) else 0:
  while (y := func(x)) if (x := 3) else 0:

- left-to-right does apply to everything else?

- *these* are discouraged:

  if (x := 3) or (y := func(x)):
  if (3) or (func(3)):
  if ((x := 3) if 1 else (y := func(x))):

IDK, I could just be resistant to change, but this seems like something
that will decrease readability -- and slow down code review -- without any
real performance gain. So, while this would be useful for golfed-down (!)
one-liners with pyline,
I'm -1 on PEP 572.

How do I step through this simple example with a debugger?

    if re.search(pat, text) as match:
        print("Found:", match.group(0))

How do I explain what ':=' is when teaching Python?

AFAIU, semantically: Python = ('equals') indicates a statement. What you
are proposing is adding an ':=' ('colon equals') assignment operator which
defines a variable which is limited in scope only in list, dict, and
generator comprehensions.

>From https://en.wikipedia.org/wiki/Assignment_(computer_science) :

> In some languages the symbol used is regarded as an operator (meaning
that the assignment has a value) while others define the assignment as a
statement (meaning that it cannot be used in an expression).


PEP 572 -- Assignment Expressions
PEP 572 -- Assignment Operator (:=) and Assignment Expressions

On Friday, April 27, 2018, Steven D'Aprano <steve at pearwood.info> wrote:

> 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
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
> wes.turner%40gmail.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180427/f8ccc869/attachment-0001.html>


More information about the Python-Dev mailing list