[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