In university, they taught us that commenting your code is not just a good thing, it’s a must. Each assignment had a portion of the grade dedicated to “documentation”. In technical interviews, and on the web, the importance of commenting your code comes up over and over again.
This misses the point entirely. It’s a classic example of a system set up incorrectly, with a proximate goal completely taking over the original root goal, the latter then being forgotten. (see proximate vs root)
The root goal was having code that is easy to read and understand, contains no difficult-to-notice tricks, behaves as expected. Comments are an extremely poor way of achieving this. They need to be written, which takes time. Writing well is not something most people can do, so just writing comments does not guarantee the achievement of the goal, the comments have to be written well. It gets worse, though. Code changes, and comments often remain unchanged. If you rename a variable, the compiler [1] will tell you that you should also rename all references to it, but if you update the code and leave the comment as is, no tool will catch that for you, so comments go stale and out of sync with the code they are commenting on. If somebody reads the comment, they will be confused — either the code or the comment is not up to date. Is the comment correct and the programmer made an error? Or is the code correct and the comment is stale? Maybe we should leave a
// TODO fix this comment if you know what's going on
comment nearby? Or do you actually have enough discipline to dig through git history, find the author, and confirm the intent? Unlikely. It gets worse still, though. Programmers often do not read comments, try to understand what the code does by tracing it, get confused, and ask the author. The author then points out: “Well, there’s a comment right in front of you describing what this code is trying to do”. “Oh… so there is… sorry” is a common interaction in such cases.
There’s also a class of comments that are utterly pointless, ones that describe in English what the code below is obviously doing. Consider this example:
# For Loop grab the Date to Day Id Dictionary
dateToDayId = data['calendar']['dateToDayId']
# For Loop grab the Date to Day Id Dictionary
mealIdToDayId = data['calendar']['mealIdToDayId']
# For Each Date inside
for date in dateToDayId:
meals[date] = int()
dayId = dateToDayId[date]
# For each Meal Id inside
for mealId in mealIdToDayId:
# Check if the Day Id belongs to the Meals
if mealIdToDayId[mealId] == dayId:
meals[date] = int(meals[date]) + 1
Comments should be approached from a default deny stance. There is a small handful of use cases that warrant comments which are discussed separately in this book, in sections on communicating intent, coding in an ideal language, and isolating complexity.
So stop achieving a pointless proximate goal that merely checks a checkbox, and focus on the root goal — write code that is easy to read, understand, reason about, that doesn’t do tricky, sneaky things, and behaves expectedly. Ways of achieving this are discussed in detail in the following sections.
[1] Languages with no compiler deserve no attention, we’re talking about writing great code here, foregoing rich automated error checking is a non-starter.
Comments
Post a Comment