[Steven D'Aprano]
really wish you would stop talking about "natural language" as if
there were only one (and it were English).
I'm fine with that. I've just had someone jump down my throat before about being overly English-centric when talking about readability.
[Steven D'Aprano]
even in English, that isn't how people read questions in general,
which is why we can still comprehend punctuation-less sentences
Yes because you can make use of other context clues. So if I wrote:
def f(person=None):
initial = person.name[0]? ...
You can anticipate the '?' at the end of the expression. Otherwise I would be clearly missing an important edge case.
None checking is often done in very close proximity to some code that might yield a None, so this should rarely be a surprise unless the coder is writing the equivalent of a garden-path sentence.
[Steven D'Aprano]
You may be able to find examples of English questions which do require
back-tracking
It's easier, I'll admit, to find example's of exclamations that require back-tracking, but it's not unheard of!
[Steven D'Aprano]
> and there are plenty of examples of Python following
> this pattern in other expressionized syntax like in comprehensions and
> ternary expressions.
But not binary operators which take only two arguments, in this case a
name and an attribute name.
Again, my proposal was never for a binary operator.
[Steven D'Aprano]
> I actually think this makes sense for expressionized
> syntax because it puts the "meat" before the "potatoes". When you're
> reading code like:
>
> initials = [person.name[0] ...
>
> You can usually guess what goes in the `...` from context
Can you?
In that example I can't even guess if that's the start of a list
comprehension or a list display. If its a comprehension, I sure as hell
can't guess the important question of what it being iterated over.
Maybe I should have fleshed out my example a little more. Usually there are plenty of context clues such that the latter part of a comprehension is more a formality for the computer's sake because computers, unlike humans, can't deal with ambiguity very well. So when you see:
def func(people): initials = [person.name[0] ...You can usually guess that, since `person` isn't a local variable, we're probably dealing with a generator so there's probably a `for` clause down the line where `person` is declared and it probably iterates over, I don't know, how about `people` and maybe there's a filter clause too. The point is that the most important information, the "meat" of the expression is up front.In the same vein, In the spirit of EAFP, it's better to get the meat of your business logic up front and do all the tedious-yet-necessary edge-case checking later just like:def func(person=None):
initial = person.name[0] ?
...The business logic comes first and the edge-case checking follows.
> so it's redundant, so it makes sense that it comes later.
If it's redundant, why don't we just leave it out?
Because redundancy from the perspective of the reader doesn't imply redundancy from the perspective of the computer. People can make sense of ambiguous language in a way that computers cant. The sentence "time flies like an arrow" has over 11 valid interpretations, yet few humans would think "oh, you're commanding me to use a stop watch to measure some behavior of common flying insects in the same way that I would use the same instrument to measure the behavior of an arrow!". If I type:
def func(people):
initials = [person.name[0] for person in people
return Counter(initals).most_common(1)[0]You, as a human, can probably guess with extremely high certainty that I meant to put a ']' at the end of the second line. In that sense, it's redundant to you, but not to the computer which doesn't know how to handle that situation. Does that make sense?