[Python-ideas] AMEND PEP-8 TO DISCOURAGE ALL CAPS
Steven D'Aprano
steve at pearwood.info
Wed Jan 30 20:24:07 EST 2019
On Wed, Jan 30, 2019 at 01:47:56PM -0600, Abe Dillon wrote:
> > Is it that really obnoxious?
>
> EXTREMELY!
I don't agree with you that the use of one or two words in a sentence
for EMPHASIS is obnoxious, and I don't writing a one-word sentence is a
good test of that.
In any case, even if it is the case that all-caps has the downside that
it draws the eye ("shouty") more than necessary, I believe that the
benefits of the convention outweigh that cost.
> > Does using upper case for constants measurably slows down coders? Can
> you cite the actual papers describing such experiments that lead to this
> conclusion ?
>
> https://www.mity.com.au/blog/writing-readable-content-and-why-all-caps-is-so-hard-to-read
> https://en.wikipedia.org/wiki/All_caps#Readability
> https://uxmovement.com/content/all-caps-hard-for-users-to-read/
> https://practicaltypography.com/all-caps.html
None of those "cite the actual papers" as requested, and only the
Wikipedia page cites secondary sources.
But that's okay, since we don't dispute that wall-to-wall paragraphs of
all-caps are hard to read, we only dispute that the judicious and
occasional use of all-caps to communicate metadata about what would
otherwise appear to be a variable hurts readability in any meaningful
sense.
It isn't very interesting to say that it takes the average programmer
(let's say) 250ms to read this line:
with open(filename, 'w') as f:
versus (let's say) 280ms to read this one:
with open(FILENAME, 'w') as f:
I don't know if that is true or not, but even if it is, I'm not
particularly interested in optimizing the time it takes to read
individual words. When it comes to coding, the time used scanning over a
line of text is typically insiginificant compared to the time needed to
understand the semantics and context.
It isn't that I particularly want to slow down reading of indivudual
words, but I'm willing to lose (let's say) 10 to 20 milliseconds to read
FILENAME versus filename, so that I don't have to spend (let's say) 30
to 120 seconds trying to determine whether or not the value of filename
has been rebound somewhere I didn't expect and that's why my script is
writing to the wrong file.
> > from my experience having a visual clue that a value is a constant or an
> enum is something pretty useful.
>
> Do you have any proof that it's useful?
Not peer-reviewed, no, but from my own experience I know that generally
speaking when I'm trying to understand the semantics of unfamiliar code
(even if that is code I wrote myself!) if I see an ALLCAPS name, I
generally know that on a first pass I can treat it as a given and ignore
it without caring about its actual value.
There are exceptions: for example, if there's a bug in my regex, then I
do have to care about the value of PATTERN. If I'm writing to the wrong
file, then I do have to care about the name of FILENAME.
But even then, I can guess that the value is only set in one place. If
there's a bug in my regex PATTERN, I can fix it once at the top of the
module, and not worry about other parts of the script or library
re-binding the value.
> Have you ever been tempted to
> modify math.pi or math.e simply because they're lower case? Have you ever
> stopped to wonder if those values change?
This is a bit of a red herring (but only a bit) because the major value
for signalling constantness is not so much as a warning to the *writer*
not to change them, but to the *reader* that in well-written code, they
haven't been changed.
Obviously you can't have the second without the first, but since code is
read more than it is written, the second occurs much more often.
When it comes to math.pi and math.e, why would you want to change
them? What is your use-case for changing them?
I actually do have one. Many years ago, I wondered whether changing
math.pi would change how math.sin, cos and tan work. So I tried this:
py> import math
py> math.cos(2*math.pi) # Period of cosine is 2π.
1.0
py> math.pi = 3 # Change the universe! π is now three exactly.
py> math.cos(2*math.pi) # Should still be 1, right?
0.960170286650366
I learned that the trig functions don't work that way. Ever since then,
I've never had any reason to want to change the value of math.pi. What
would be the point?
> If the socket library used packet_host, packet_broadcast, etc. instead of
> PACKET_HOST, PACKET_BROADCAST, ETC. would you be confused about whether
> it's a good idea to rebind those variables?
If they are variables, then by definition they must vary. If they vary,
there must be reasons to rebind them. Since these are not flagged as
"private" with a leading underscore, presumably they are part of the
public API, so I would expect that, yes, rebinding those variables was a
good idea.
Since I'm not a domain expert when it comes to sockets, I would probably
spend many minutes, maybe hours, trying to work out what part of the
socket API requires me to set these global variables, and why.
But in reality, since they are clearly flagged as constants, I can
assume that they are intended as read-only constants, not global
variables. I don't need to be a domain expert on sockets to know that
rebinding PACKET_HOST is a bad idea, I just need to know that it isn't
supported by the socket module.
(The danger in asking rhetorical questions is that sometimes the answer
isn't the one you expected.)
> It seems to me that nobody is actually considering what I'm actually
> talking about very carefully. They just assume that because all caps is
> used to convey information that information is actually important.
Or maybe some of us have thought carefully about what you have said, and
concluded that you are making an unjustified micro-optimization for
reading time as measured by eye-tracking time over individual words, at
the cost of total editing and debugging time.
> Not just
> important, but important enough that it should be in PEP-8. They say I
> should just violate PEP-8 because it's not strictly enforced. It is
> strictly enforced in workplaces.
Clearly it isn't "strictly enforced". Because the single most important
rule of PEP 8 is the one mentioned right at the start about knowing when
to break all the other rules.
If your workplace forbids any exceptions to the other PEP 8 rules, then
they are violating the most important PEP 8 rule of all.
> > Surely, I'd hate reading a newspaper article where the editor generously
> sprinkled upper case words everywhere
>
> Exactly. If it's an eye-sore in every other medium, then it seems likely to
> me, the only reason programmers don't consider it an eye-sore is they've
> become inured to it.
It isn't an eyesore in every other context.
You are making a logical error in assuming that since
wall-to-wall all-caps significantly hurt readability, so much
individual all-caps words. This is simply not correct.
Drinking six litres of water in a single sitting will
likely kill an adult; therefore (according to your
reasoning) we shouldn't drink even a single sip of water.
https://www.medicaldaily.com/taste-death-ld50-3-popular-drinks-can-kill-you-298918
Even if eye-tracking experiments show that it takes a fraction of a
second longer to read that one word, that doesn't correspond to "hurting
readability" in any meaningful sense.
Optimizing for eye-tracking time for its own sake is not a useful thing
for programmers to worry about.
> > but analogies only go so far, reading code have some similarities with
> reading prose, but still is not the same activity.
>
> CAN you articulate what is DIFFERENT about READING code that makes the ALL
> CAPS STYLE less offensive?
You are misusing the word "offensive" there. Please don't use it to mean
"hard to read" or "annoying".
Again, to answer your rhetorical question in a way you probably hoped it
wouldn't be answered: because we don't write wall-to-wall all-caps code
(at least not in Python). We're not likely to have six all-caps names in
a single expression; we're probably not likely to have six all-caps
names in an entire function.
Consequently the cost of reading the all-caps word is tiny, and the
benefit is greater.
Just as it is for using all-caps for initialisms and acronyms like AFL,
USA, FAQs, LD50, LED, PRC, PC, etc. Or for the occasional use for
emphasis. Etc.
--
Steve
More information about the Python-ideas
mailing list