Friday Finking: Contorted loops

Avi Gross avigross at verizon.net
Mon Sep 13 17:50:48 EDT 2021


Peter,

Choosong when and how to comment is an invidual thing and certainly the
interpreter does not care.

Yes, I gave an example where my comment used inner/outer as the words but
more often I am more explicit along the lines you mention. Sometimes I
include most of the text into the comment such as
if x <10 {
... MANY LINES
} # END if x <10

But please understand the goal is many fold. One simple goal is that by
having to comment the code, you sort of have to explain it to yourself and
use the opportunity to see if it makes sense and matches any requirements or
perhaps even adds new functionality not already documented. 

Secondarily, it is for you to read much later when returning to the code to
refresh your memory.

In many organizations, including where I worked, there can be levels of code
review that work better if others have a clue what they are reviewing or
why.

And of course, others often take over your code or examine it.

At one point I was doing field support on a project, way back when it meant
something to carry a beeper. I had written some of the code but the vast
majority was done by others on the team. When I got beeped at 3 AM from a
place like Japan, I often had to make rapid decisions on how big a problem
was and whether I should wake someone up, including developers and their
management or even rarely upper management. I often dove into the code to
find the likely locus of a problem and even to see if I could spot the place
that might be patched. That often let me wake up the right person and work
with them to expedite an emergency change. Even in less chaotic or major
times, I had to work with getting a problem acknowledged and scheduled for
inclusion in a future release. Being able to read all kinds of source code
and figuring it out quickly was important and sometimes comments were
helpful. In particular, some people did not need to be woken up if I was
able to see the problem was not in their code!

Comments do often have a rather weird purpose. Sometimes we collected
metrics on how many lines of code were new or changed between releases and
unless the tools removed comments, ...

But I have found over the years that too many comments are badly done. For
example, rather than ending every line of a function definition with all
kinds of things that clutter things, it is often better to place a few block
comments above a function definition explaining the general purpose of the
function, what inputs are expected on the command line, what assumptions are
made about them, whether it uses any other resources (including dreaded
global variables) and what it returns or what errors it may generate and so
on. You can also discuss the overall idea of how the function does the job.
Then, within the function, you can have smaller mainly one-liners like:
   #  This section checks if the variables are all within expected bounds.
   ...
   # Combine ...
   ...
   # quit if not satisfied
   ...
   # Make the changes requested.
   ...
   # return successfully with a structure holding ...
   ...

Again individual taste. My personal commenting style has evolved and varies
from language to language. In many cases, I have used well-chosen variable
names that are meaningful to me but not keywords. Sadly for some others, I
sometimes choose variable names in other human languages, sometimes
transliterated as sticking to ASCII requires. Most people are not able to
even guess, so say commenting in Hungarian or German or Hebrew may only be
of use to me and other weird people.

I do find that for frequent enough usage of something, such as an object
like a deque, you get to know it so well that you may stop commenting on how
you are using some built-in feature as it seems routine.

-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net at python.org> On
Behalf Of Peter J. Holzer
Sent: Monday, September 13, 2021 3:28 PM
To: python-list at python.org
Subject: Re: Friday Finking: Contorted loops

On 2021-09-12 17:11:58 -0400, Avi Gross via Python-list wrote:
> Yes, large units of code, and even smaller ones, may be a chore to 
> figure out. Arguably harder when you use indentation and the next/last 
> parts are not even on the same screen as the rest. Sometimes you want 
> to use a split-screen in some editor to line up the two parts or some 
> other technique.
> 
> But my suggestion is to COMMENT things well and I mean too much!
> 
> do {
>    <CODE>
>   } while <COND>
> 
> Why not add a comment at the top like:
> 
> # The following loop has a WHILE clause controlling it at the end.
> 
> do { # until the while clause below
>    <CODE>
>   } while <COND> # End of the do loop.

Because those comments don't tell me anything that I as a C programmer don't
already know. Even though do/while loops are relatively rare, I've seen
hundreds of them. Seeing "do {" and recognizing it as the top of a do/while
loop takes absolutely no conscious thought - reading a comment does.

> My code tends to have brief comments especially when I have nested 
> constructs such as multiple nested loops or in sequence, or if 
> statements inside others. The comment often looks like
> 
> ... # END of inner if
> 
> ... # END of outer if

Those are a bit better, but they still don't help much. What is the "inner
if", what is the "outer if"? Chances are that I have to find the
corresponding if to find out - I can do that without a comment, too.

There are end-of-construct comments which I do find useful (at least
occasionally) but those are semantic.

Imagine a somewhat longish function which read several files which are
comprised of records which are comprised of field.

for file in files:

    some setup for each file here

    for record in file:

        some setup for each record here

        for field in record:

            process field

        do some postprocessing for the record

    do some postprocessing for the file

If each of these blocks is longer than a few lines you might lose track
where you are, so some comments might help:

for file in files:

    some setup for each file here

    for record in file:

        some setup for each record here

        for field in record:

            process field

        # end of field loop

        do some postprocessing for the record

    # end of record loop

    do some postprocessing for the file

# end of file loop


Note that the comments say which part of the input the loop is processing,
not just that it is the end of a loop or "the outer loop", "the intermediate
loop" and "the inner loop" or some other purely syntactic information.

(In most cases I would just break up such a function into smaller functions
instead of adding comments, though)

        hp

-- 
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp at hjp.at         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"



More information about the Python-list mailing list