[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] PEP 572: Assignment Expressions

On Mon, Apr 30, 2018 at 11:32 AM Chris Angelico <rosuav at gmail.com> wrote:

> On Tue, May 1, 2018 at 12:30 AM, Mark Shannon <mark at hotpy.org> wrote:
> > List comprehensions
> > -------------------
> > The PEP uses the term "simplifying" when it really means "shortening".
> > One example is
> > stuff = [[y := f(x), x/y] for x in range(5)]
> > as a simplification of
> > stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]

> Now try to craft the equivalent that captures the condition in an if:

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


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

Longer, but way more readable and debuggable if you're into that.  This has
worked for us many years and only a handful of people complained about

OTOH, I see plenty of people complaining that nested list comprehensions
are hard to read.  In my own code reviews I ask people to avoid using
complex comprehensions all the time.

> Do that one with a lambda function.

Why would I?  Is using lambda functions mandatory?

> > IMO, the "simplest" form of the above is the named helper function.
> >
> > def meaningful_name(x):
> >     t = f(x)
> >     return t, x/t
> >
> > [meaningful_name(i) for i in range(5)]
> >
> > Is longer, but much simpler to understand.

> Okay, but what if there is no meaningful name? It's easy to say "pick
> a meaningful name". It's much harder to come up with an actual name
> that is sufficiently meaningful that a reader need not go look at the
> definition of the function.

That's a weird argument, Chris :-)

If `f(x)` has no meaningful name, then *what* is the result of the
comprehension?  Perhaps some meaningless data? ;)

> > I am also concerned that the ability to put assignments anywhere
> > allows weirdnesses like these:
> >
> > try:
> >     ...
> > except (x := Exception) as x:
> >     ...
> >
> > with (x: = open(...)) as x:
> >     ...

> We've been over this argument plenty, and I'm not going to rehash it.

Hand-waving the question the way you do simply alienates more core devs to
the PEP.  And PEP 572 hand-waves a lot of questions and concerns.  Asking
people to dig for answers in 700+ emails about the PEP is a bit too much,
don't you agree?

I think it's PEP's author responsibility to address questions right in
their PEP.

> > def do_things(fire_missiles=False, plant_flowers=False): ...
> > do_things(plant_flowers:=True) # whoops!

> If you want your API to be keyword-only, make it keyword-only. If you

Another hand-waving.  Should we deprecate passing arguments by name if
their corresponding parameters are not keyword-only?

Mark shows another potential confusion between '=' and ':=' that people
will have, and it's an interesting one.

> want a linter that recognizes unused variables, get a linter that
> recognizes unused variables.

Many want Python to be readable and writeable without linters.

> Neither of these is the fault of the
> proposed syntax; you could just as easily write this:

> do_things(plant_flowers==True)

> but we don't see myriad reports of people typing too many characters
> and blaming the language.

Strange. I see people who struggle to format their code properly or use the
language properly *every day* ;)