[Python-ideas] Proposed alternative postfix syntax [was PEP 505: None-aware operators]

Steven D'Aprano steve at pearwood.info
Sun Jul 29 07:45:07 EDT 2018


On Sun, Jul 29, 2018 at 02:12:22AM -0500, Abe Dillon wrote:

[I said this]
> > Python is very little like natural language. Your earlier idea that
> > attribute access spam.eggs is like natural language (in English) because
> > its only a few characters different from "spam's eggs" really doesn't
> > hold up. Apart from the word order, there's no similarity.
> 
> I feel like you're being willfully dense about this.

Am I? Your exact words were:

  My point is that '.' is unobtrusive, so it's not *that* different from 
  `person name' which isn't *that* different from `person's name`.

so you absolutely are claiming that dot access "isn't *that* different" 
from the possessive in English.

The dot might be small, but the last thing we want if for the dot to be 
unobtrusive. We want it to stand out and be obvious, so we can never 
mistake 1.5 for 15 or (say) "appbuild" for "app.build".

(The first is a variable called "appbuild", the second is a build method 
or attribute invoked on a variable called "app". Very different things 
indeed. We really don't want to mistake one for the other.)

This is one important reason that most programmers use monospaced fonts 
for code, so that the dot takes up as much space and any other character 
and stands out more.

The ?. syntax is obviously different from regular dot, but surely that 
is an *advantage* not a disadvantage? Things which do something 
different should look different.

One of the problems with David Mertz's counter-proposal for a magic 
None-aware proxy is that we can't tell the difference between 

    spam.eggs

and

    spam.eggs

where one of them is magic and the other is not. So we have a nice, 
clear, obvious difference in syntax so that at a glance the reader can 
instantly distinguish between dot and maybe-dot, and you are complaining 
that it is too clear, obvious and easily distinguishable compared to a 
regular dot.


> [Steve D'Aprano]
> > I don't know that Python has any binary operators which are split
> > into an infix part and a postfix part.
> 
> That's not at all what I proposed.

That's exactly what you proposed, you just didn't realise it. See 
below. Your syntax is

    foo.spam?

where the dot and the question mark together make a new binary operator. 
They aren't really delimiters like the parentheses in func( ... ) or the 
square brackets in seq[ ... ] but two halves of a single operator (or 
operator like construct) with an infix part (the dot) and a postfix part 
(the question mark). They certainly can't be two separate operators, a 
dot and a question mark.

I don't know how the Python parser itself will deal with this, but 
consider the syntax from the perspective of a reader. You suggest:


> I'm proposing:
> 
> spam.eggs.cheese.aardvark?

Given that, we read the code as:

   spam
   normal dot, so get the attribute eggs
   normal dot, so get the attribute cheese
   normal dot, so get the attribute aardvark 
   question mark, rewind to the beginning and start again:
   spam
   maybe-dot, so maybe get eggs, or None
   maybe-dot, so maybe get cheese, or None
   maybe-dot, so maybe get aardvark
   

I'm not saying that's what the parser will have to do (although I 
suspect it will need some sort of look-ahead, or backtracking, to parse 
this) but that's certainly how I'll read this.


> A single POSTFIX operator that has a high priority in the order of
> operations.

I don't think that will do what you think it will do. If ? is a normal 
unary postfix operator then its operand here:

    spam.eggs.cheese.aardvark?

will be (spam.eggs.cheese.aardvark), which defeats the purpose of having 
a maybe-dot operator. By the time the ? operator is called, the regular 
dot operators will have already been called.

It may be possible to get the syntax you prefer, but readability-wise, I 
think it is magical and confusing to have a postfix symbol at the end of 
an expression *retroactively* change the meaning of symbols occuring 
before it in the expression.

I expect it will also be a bug-magnet when we need to mix regular dot 
and maybe-dot in the same expression:

    spam.eggs?.cheese  # eggs might be None, but spam won't be

would need to be written as

    (spam.eggs).cheese?

but who is going to remember those parentheses? Instead I expect people 
will consistently write:

    spam.eggs.cheese?

thinking the ? applies only to *one* dot, not all of them, and wrongly 
suppress exceptions when spam is None (which ought to be treated as a 
bug).



-- 
Steve


More information about the Python-ideas mailing list