| I do this, and I'm a senior dev. I find it an absolute God-send when I come back to the code months or years afterwards. I am much, much faster at parsing and reading English than I am at code. When I'm coming back to some code for maintenance work, I am not normally trying to understand code deeply, I am usually trying to get a quick overview of it, and then locate a specific thing it's doing, to parse it more deeply. Comments like this allow a skim read for locating what you're after, and - as you identified - normally come in as I'm detailing the process, which means, doubleplusgood, you also get to see what I was thinking as I was writing the original code. > One's code should be written in such a way as to inform a programmer maintaining the code to its purpose and utility Almost. But you forgot "as quickly as possible". > But it also means that comments should only be used when you're going against convention or doing something hack-ish on purpose. I suggest that with experience, especially experience of being the curmudgeonly old senior dev on very mixed ability teams, with codebases sometimes a decade old, where the code is occasionally insane, you will start to be thankful of all clues the code can possible offer up as to why people do what they do. |
I read tonnes of code. I've formed my opinion by reading and reviewing tonnes of code. I'm cautious about jumping to conclusions.
In my experience the kind of code that requires comments to act as "guideposts," (if I've correctly interpreted your meaning) is suffering from symptoms of a larger problem: poor design. When I read code that comes from people who use this style I often find that their functions go on for ~70 LOC, use at least 3 levels of nesting, and are littered with comments to explain what is going on.
More often than not I was able to show them that they could break these procedures out into compose-able functions and drop the comments. With the right data-structures they could avoid excessive loops and conditionals. And with the right unit tests if they ever needed to change the implementation of a function they would know right away if they broke something. Suddenly they didn't need so many comments because their functions were < 10 LOC and self-explanatory -- the name of the function gave its meaning and the higher-level code read more like an explanation of the process without all of the details of how the machine should perform it.
That, of course, is the best case scenario. I've worked on a gnarly C++ web application that was more than a decade old and survived several attempts to port and extend it with Python. But you can deal with that too. Just try not to touch the legacy code. ;)