[Python-ideas] PEP 505: None-aware operators

Giampaolo Rodola' g.rodola at gmail.com
Mon Jul 23 18:05:14 EDT 2018


On Mon, Jul 23, 2018 at 6:53 PM Steven D'Aprano <steve at pearwood.info> wrote:
>
> On Mon, Jul 23, 2018 at 02:04:17PM +0200, Giampaolo Rodola' wrote:
> > "a?.b" does two and that's a fundamental difference (explicitness).
>
> How is "two things" less explicit than "one thing"?
> Comments like the above is why I think that "explicit" and "implicit"
> are used to mean "I like it" and "I don't like it" rather than being
> objective arguments, or indeed having anything to do with explicitness
> or implicitness.

This:

    v = a?.b

...*implicitly* checks if value is not None [and continues execution]. This:

    v = a
    if a.b is not None:
        v = a.b

...*explicitly* checks if value is not None and continues execution.
If for some reason '?'[ is also going to swallow LookupError then
*that* would further decrease explicitness, because LookupError would
be nowhere in sight, the same way "if", "is", "not", "None", ":", "new
line" are nowhere in sight in the 'a?.b' example. Some argued "A ?? B"
is less explicit than "A if A is not None else B" for the same reason.
One may argue that silently returning None instead of raising
AttributeError is also less explicit.
This - and this only - is my argument about explicitness. It doesn't
have to do with how many things are hidden behind an import statement
or what happens on sorted() (that's comparing apples and oranges).
I hope it's clear now.

> > It
> > does so by introducing a brand new operator ("?") which can be spelled
> > in two forms ("a?.b" and "a?[b]") by using two adjacent symbols not
> > interrupted by any space, which is an absolute first in the Python
> > syntax
>
> It isn't a first. Many existing operators use two adjacent symbols not
> interrupted by a space:
>
> e.g.  ==  <=  >=  !=  **  //  << >> +=  -=  *= etc.

You say 'a == b'. You can't say 'a ?. b' (not that it matters, it
would be less intuitive anyway). You can't because '.?' is the only
couple of contiguous symbols requiring "something" before and after
with no spaces in between, and that's a first in the language. The
argument about this is that it's ugly and less readable. My additional
argument at the beginning of this thread was that if you add PEP-572
to the mix you dangerously enter into Perl territory:

    foo(x=(x := a?.b?[c] ?? d))

> > and that's the second and fundamental difference. I cannot move
> > the same criticism to the "a.b" form: it's simpler, it does one thing
> > and it uses one symbol.
>
> You criticised ?. because it can interupt left-to-right execution:
>
>     a?.b?.c?.d
>
> True. But so can a single dot:
>
>     a.b.c.d
>
> is no more guaranteed to execute all the way to the right.

The difference is that 'a.b.c.d' will result in AttributeError as soon
as something is None while 'a?.b?.c?.d' will return None instead.

> Likewise the logical operators "or" and "and" are designed to
> short-circuit. If ?? and friends are a mistake because they
> short-circuit, why aren't "or" and "and" mistakes?
> I'm not asking this as a rhetorical question. If you think there is a
> reason why it is okay for or/and to short-circuit, but it is bad for ??
> and friends to short-circuit, then please explain why they are
> different. I will be very happy to listen to your arguments.

The argument about this is that '?.' short-circuits execution
*silently*. Instead of AttributeError you get None. You may chain ?.
in order to lazily traverse a long tree, inadvertently assign None to
a variable, continue code execution and fail later rather than sooner:

     email = request?.context?.user?.email  # None
     ...
     sendmail(subject, body, email)

Some (Antoine) rightly argued this may even have security implications
(replace 'email' with 'password').

-- 
Giampaolo - http://grodola.blogspot.com


More information about the Python-ideas mailing list