Comments are a bit tricky to argue about, because of so many pre-existing conceptions – and the spectrum somewhat ranges from a) insecure customers who would prefer that every line of code has its own comment to z) overconfident programmers who believe that every comment is outdated in the second it is written. Major problems with these approaches are
a) leads to a lot of time and keystrokes wasted for stuff that is self-explanatory at best and, indeed, outdated in the near future;
z) some implementations really can only be understood with further knowledge, and this information really has to be attached right to the place where it is used (“co-located”).
So naturally, one should neither dimiss them as a whole, but also really care about whether they actually transport any useful information. That is, useful for any potential co-developer (that is most likely yourself-in-a-few-weeks).
The question of “Whether” might stay most important – because most comments can really be thrown out after giving your variables and functions descriptive names, but lately I found that there can be quite a difference in readability with various ways of placing a comment.
Compare the reading flow of the following:
class EntityManager:
entities: List[Entity]
session: Session
other_properties: OtherProperties
# we cache the current entity because its lookup can take time
_current_entity: Optional[EntityInstance] = None
_more_properties: MoreProperties
...
vs.
class EntityManager:
entities: List[Entity]
session: Session
other_properties: OtherProperties
_current_entity: Optional[EntityInstance] = None
# we cache the current entity because its lookup can take time
_more_properties: MoreProperties
...
Now I suppose that if one is not accustomed, the second one might just look wrong because comments are usually placed either before the line or to the right of it. The latter option is left out here because I figure it should only be used when commenting on the the value of this declaration, not the general idea behind it (and making me scroll horizontally is a mischevious assault on my overall work flow; that is: motivation with working with you again).
But after I tried around a bit, my stance is that there are at least two distinct categories of comments,
- one that is more of a “caption”, the one where I as a developer have to interrupt your reading flow in order to prevent you from mistakes or to explain a peculiar concept – these ones I would place above.
- one that is more of an “annotation”, that should come naturally after the reader has already read the line it is refering to. Think about it like a post in some forum thread.
For some reason the second type does not seem to be used much. But I see their value, and having them might be preferable than trying to squeeze them above the line (where they do damage) or to remove them (where they obviously can not facilitate understanding).
One of my latter attempts is writing them with an eye-catching prefix like
index = max_count - 1
# <-- looping in reverse because of http://link.to.our.issue.tracker/
because it emphasizes the “attachment” nature of this type of comment, but I’m still evaluating the aesthetics of that.
Remember, readability can be stated as a goal in itself because it usually is tightly linked to maintainability, thus reducing future complications. Some comments are just visual noise, but others can deliver useful context. But throwing the “useful context” in the face of your reader before them even being half awake will not make them happy either, and therefore – maybe think about the placing of your comments in order to keep your code like a readable story.
Generalizations
It might well be that you dislike my quick examples above, which were not real examples. But the “think of where” also applies to other structures like
if entity_id is None:
# this can happen due to ...
return None
vs.
# TODO: remove None as a possible value in upcoming rework
if entity_id is None:
return None
vs.
if entity_id is None:
return None
# <-- quit silently rather than raising an exception because ...
or similar with top-level comments vs. placing them inside class definitions.
You see, there are valid use cases for all varieties, but they serve difference intentions each.