DEV Community

Should comments in code be considered failures in coding?

Ross on August 26, 2019

Uncle bob says: A comment is a failure to express yourself in code. If you fail, then write a comment; but try not to fail.— Uncle Bob Martin ...
Collapse
 
stereobooster profile image
stereobooster • Edited

This is false dichotomy that you can use only self-explanatory code or only comments. You can use both. Self-explanatory code can't answer the question "why" (at least not as easy as a comment can).

Collapse
 
loribbaum profile image
Lori Baumgartner

💯 this! We recently had a case where two keys in a 3rd party API response appear to return the value 99% of the time, and we were oblivious to that 1% until the 3rd party maintainer told us they were different.

To remove the need for comments in our code ingesting that API, we would have had to rename database table columns and change all of our internal naming conventions around that attribute - which would not have been possible because we integrate with multiple 3rd party APIs that all use their own naming conventions. So refactoring code to work for one API would require us adding comments to explain why the other API's responses didn't match up.

Instead of those code changes, a one-line comment explaining the why is all we'll need to do to clarify and prevent further confusion.

Collapse
 
rossdrew profile image
Ross • Edited

But that's very obviously a failure, right? A failure to communicate, receive or understand requirements properly. If that miscommunication wouldn't have happened and the comment is unnecessary. so in this case I would say it's very directly the comment communicates a failure in code.
Yes it's the easy option here and possibly the right one, but it's still required because of a failure. That is technical debt.

Thread Thread
 
loribbaum profile image
Lori Baumgartner

With the context of how this particular app is built and our limitations, I don't agree with that - and I think is the general gray area that I believe is unavoidable in most legacy codebases.

Even if we were to ignore the miscommunication that happened that resulted in us using the wrong key in the first place, we still have to rectify the differences between the different APIs that our app is ingesting to populate one database. As much as I would prefer it, sometimes you have to make a choice and stick with it - in this case, a tricky naming problem that doesn't have a solution that fits all sources of data.

I understand and agree with your general tenet, but the world isn't black and white and I think it's a dangerous mindset to think that there is a "right" way to write code that will guarantee other users will understand its purpose.

Thread Thread
 
rossdrew profile image
Ross • Edited

we still have to rectify the differences between the different APIs that our app is ingesting to populate one database

Which is why database objects are -in good design- considered separated from runtime objects so this sort of thing is easy and more flexible. Then they can be called whatever you like in your db.

You are saying that a mistake was made and it resulted in a comment but still defending the notion that comments don't indicate mistakes. You are using what many would consider to be bad design (tightly coupled runtime and domain objects with database objects) explained in comments as an argument that comments aren't always compensation for mistakes.

I know the world isn't black and white and there are exceptions to every rule and it's important to understand that but without the rule and pushing into that grey area as much as possible then the grey area pushes back, which seems to have happened quite strongly in the case you mention.

Thread Thread
 
stereobooster profile image
stereobooster • Edited

Readability of code depends on the reader 🤝. And sadly there is no single set of rules. Some people find Lisp hard to read, some work with it just fine. Some people prefer OOP-ish style of code some prefer functional-ish, and some prefer strange mix ¯\_(ツ)_/¯.

Some people would not find code self-explanatory even if others think it is. What to do in this case?

1) Explain code?
2) Instead of explaining it each time put this explanation in the codebase (in form of a comment)?
3) Rewrite code, until everybody agrees?

From my PoV, all can be valid options, depending on the situation. The situation can repeat whenever team working with this code changes, or changes are reviewed by one part of the team but on the other.

PS remembered about this: SPACE SHUTTLE code

Collapse
 
samuraiseoul profile image
Sophie The Lionhart

I feel for the most part comments should not be necessary and are a failure.

That said, I think in the case of describing why you are doing something(in the case of a strange business requirement or marketing has decided to name something that makes things unclear) then a comment is a good fit.

Also sometimes due to an outside library or dependency or new tech, you need to do something hacky. There a comment due to why its hacky, what went wrong, what part of it is the hack, and how to investigate if there's a better solution when a dev comes to it later, is a good choice. In addition maybe make a card to document that tech debt and investigate it in six months or a year can also be a good idea there. Accept that you've 'failed' but also sets you up to maybe succeed later. :D

Collapse
 
combinatorylogic profile image
combinatorylogic

What are you all people coding that "comments are not necessary"?

Comments are absolutely mandatory, because code does not have any ways whatsoever of conveying all that essential information. Code tells you the "how" part of the story, and it's the most trivial part, derived nearly mechanically from the requirements. This coding part does not deserve even a tiniest fraction of attention it's getting from all those "clean code" practitioners.

The important part is the though process that lead to this particular wording of the requirements that was ultimately translated into the code. And if it's documented elsewhere, not along with the code itself, it'll get out of sync in no time.

Collapse
 
rossdrew profile image
Ross • Edited

Comments are absolutely mandatory, because code does not have any ways whatsoever of conveying all that essential information

I feel an example is required.
Here's my own personal project. Comment exist for documentation and in locations where my implementation has failed, I challenge you to suggest where comments are mandatory to increase uptake. Where unit tests and Javadoc fail to be more than enough.

Tell me where my code isn't "conveying all that essential information".

github.com/rossdrew/emuRox

And if it's documented elsewhere, not along with the code itself, it'll get out of sync in no time.

20 years I've been a developer. I've never worked somewhere where 90% of the in code comments are found to be out of sync with the code they comment.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

I challenge you to suggest where comments are mandatory to increase uptake

How can I do it? The information is already missing. It's not there. It cannot be deduced. You decided to withhold it, and since telepathy is not among my strong skills, I'm not in a position to suggest what exactly was on your mind when you wrote all of it. That's your job to explain all the background.

I don't know what were your performance considerations, why exactly did you choose this particular (and quite unusual) way of representing a CPU state, how do you mitigate the timing issues (as it's clearly not a cycle accurate emulator), and so on. It's all in your head, not written down anywhere in the code. Maybe you have some notes, maybe even a wiki, a pile of .doc files, etc., but it's all inaccessible from any of the relevant code. Finding it out requires effort at the very least, and asking you, the author, in the worst case scenario.

You need external sources in order to read your code, which is not a very good practice.

Well, 6502 won't ever change, it's solidified forever in the history, but think of a case where you're implementing some particular edition of an evolving standard - you'd have to put all the relevant standard paragraphs into your code in order to make it readable, along with documenting all your decisions on how to interpret undefined behaviour and implementation-specific cases.

Still, your code cannot be read properly without looking at a 6502 ISA spec on a side. And that's your conscious decision - you could have mixed it into your code to make it easier for anyone who'd read and maintain it.

20 years I've been a developer. I've never worked somewhere where 90% of the in code comments are found to be out of sync with the code they comment.

I simply don't believe it. I see stale Confluence pages pretty much on a daily basis. Not to mention that even if they're relevant, they're only relevant to the master and won't help at all if you're reading some older release branch. Confluence pages are not versioned under the same git repository as your code, and that's exactly what's wrong with them.

Have a look at some proper Literate Programming examples - TeX The Book, or some lighter read like, say, this one: wyag.thb.lt/ - or this one combinatorylogic.github.io/mbase-d...

When code is only an illustration to a story, it reads much better than when the actual story is somewhere out there, requiring quite a bit of an effort to recover and put together. You see the big picture and all the details simultaneously, and you're naturally avoiding writing any excessive code.

Thread Thread
 
rossdrew profile image
Ross • Edited

Still, your code cannot be read properly without looking at a 6502 ISA spec

That is not the case at all. It seems you want every piece of information about the domain, about what the developer was thinking at the time, about every considerations has or ever will be. You want every choice to be documented even when they weren't a concern such as cycle accuracy and performance.

Firstly, that is not literate programming (it's a confused version of literate programming ad nauseam) and secondly good design in this case in Java is literate programming. Following the guidance of small methods, well designed class hierarchy and good Javadoc does in fact meet the standards of "code within comments" rather than your suggestion of "[excessive] comments within code".

Thread Thread
 
combinatorylogic profile image
combinatorylogic

It seems you want every piece of information about the domain, about what the developer was thinking at the time, about every considerations has or ever will be.

Yes. That's what I want to be assembled in one place. Because this is the important part. The code itself is only a derivative of all of these stuff.

You want every choice to be documented even when they weren't a concern such as cycle accuracy and performance.

The fact they're not a concern must be clearly documented, along with a reasoning.

Following the guidance of small methods,

That's my another pet peeve. I hate the very idea of radically small methods - it goes against the far more reasonable pattern-matching based approach to expressing things.

"code within comments" rather than your suggestion of "[excessive] comments within code"

Literate Programming is exactly code within comments, with more text than code. You can view it as code interleaved with tons of "excessive" comments if you wish, but in reality it's the code that's embedded in the story, not the other way around.

Collapse
 
combinatorylogic profile image
combinatorylogic

Uncle bob is not a practicing programmer, he's a career preacher. Nobody should pay any attention to anything this buffoon is saying.

Literate Programming is the right way to go, and it's exactly the opposite to whatever he's preaching.

As for keeping comments up to date - that's exactly what code reviews are for. And it's far easier to do with comments which are in line, close to all the code changes you're making. What is really insane is to try to keep all your fancy Confluence pages documenting the design decisions in line with the code, and good luck coming back to a 5 years old branch to only find stale links and no relevant information in any external documents whatsoever.

Collapse
 
rossdrew profile image
Ross

As for keeping comments up to date - that's exactly what code reviews are for.

"code" reviews are for keeping "comments" up to date. Never in my 20 years have I seen this done well. Pushing for more expressive design always works.

Collapse
 
combinatorylogic profile image
combinatorylogic

And did you ever systematically practice Literate Programming approach? It works much better than any of the "clean code" madness.

There is simply no such a thing as an expressive design. Any design is still missing all of the background train of thought that lead to it.

Thread Thread
 
rossdrew profile image
Ross • Edited

And did you ever systematically practice Literate Programming approach?

Yes and like I've said elsewhere, I'm not entirely sure you've understood the concept you are trying to teach me. "Code within comments" isn't what you are preaching right now.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

"Code within comments" isn't what you are preaching right now.

Why? That's exactly the approach I'm talking about. You write down the story, meticulously, and you illustrate the story with a code that implements it. Not the other way around.

Thread Thread
 
rossdrew profile image
Ross

I can tell you exactly 0 programmers I've met in my life who when given the instruction...

write down the story, meticulously

...would not quit or skim the documentation part, leaving you with mismatched, unverifiable rubbish all around your code. I can think of no way to keep that documentation up to date or to verify that the code and the comments do the same thing.

Collapse
 
jankapunkt profile image
Jan Küster 🔥 • Edited

Should code be written in a way that's expressive enough on it's own?

The majority of my code is written as expressive as possible. Especially naming of variables, functions, interfaces and classes can already have a great impact here.

Note that this is also a great responsibility for the architects and lead engineers who design and model the software architecture. If they fail on their level to provide clear and understandable interfaces and APIs, you can't clean this mess up with expressible code.

If you disagree, what are your thoughts on keeping comments up to date with changes?

I would always comment parts of code where event minor changes can have big consequences, not matter whether the code is expressible or not. It's like the "STOP" or "DANGER" sign to cause attention.

And of course any externally consumed API is documented regarding it's functionality, expected input / output and potential exceptions.

Is there a grey area? Examples?

Hard to create definite "rules" on when code should be documented or not. I think a good indicator is when parts of the code are heavily discussed during a code review it should be documented with whatever was the controversy and how it got resolved.

Collapse
 
rossdrew profile image
Ross

Sounds like the entire thread has reached a consensus that comments do indicate mistakes but that sometimes mistakes and therefore comments are necessary.

And that the original statement is pretty accurate (except, sometimes it's also other peoples failures)

If you fail, then write a comment; but try not to fail.

Collapse
 
combinatorylogic profile image
combinatorylogic

I'd say lack of comments is a very clear indication of a pile of crawling creepy mistakes.

It's an indication of a wrong paradigm choice that lead to proliferation of a boilerplate code - all that code should have never existed in the first place.

It's an indication of a decision to forget all the important thought process that lead to the current code architecture, which will unavoidably lead to repeating the already made mistakes over and over again while maintaining this code in the future.

It's an indication of a lack of discipline in general, which, by proxy, results in a high number of bugs.

I'd stay as far away as possible from an uncommented code.

Thread Thread
 
rossdrew profile image
Ross

I'd say lack of comments [is] an indication of a wrong paradigm choice

Surely if your paradigm is correct, it easier to express without comments. I would say the exact opposite. Bad paradigm choice leads to need for comments to explain compromises made due to lack of express ability. Code is made closer and closer to English to make it more expressive, if you need to drop into English, the abstraction has failed to be expressive enough.

Thread Thread
 
combinatorylogic profile image
combinatorylogic • Edited

Even if your code reads just like plain English and it's as close to semantics of your problem domain as possible, it still only explains the "how" part. The "why?" part is missing.

Thread Thread
 
rossdrew profile image
Ross

yawn

Collapse
 
lukewestby profile image
Luke Westby • Edited

As a contradictory scenario, consider that a lot of popular languages and frameworks have core functions that are confusingly named or poorly documented or have unexpected behavior for particular sets of arguments. It’s not malicious; everyone generally does their best and choice quality deteriorates over time as expectations rise. But core functions are how we accomplish our goals on those platforms so we don’t have the choice to avoid them. I’m not sure how I would explain a specific use of such a function to future developers or warn them of its inherent and unavoidable precariousness without a code comment.

I’m not so much a fan of looking for general rules about code comments and quality to make judgements of highly contextual choices. I’m much happier accepting ambiguity and examining behavior in terms of the systems and externalities that shape it. On this subject in particular I’ve learned to understand that “this code is a failure” often just means “I personally don’t like it” and nothing more. I’ve read a lot of what Bob Martin has to say and I don’t really get the sense that he agrees.

Collapse
 
rossdrew profile image
Ross

But again that describes a mistake, covered by a comment right? You are saying that yes, comments indicate mistakes but sometimes they are necessary. That's a different argument entirely.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

In most cases I could agree with this. However the big hole in this universal statement, is that it has to assume that a given language is capable of clearly expressing any possible situation. They aren't.

Where it goes even more off the rails is when we are talking about performance optimizations. There is a funny comment war where the RavenDB CTO reviews the code of LightningDB. The RavenDB guy is picking on things like reusing a variable for multiple purposes. The LightningDB guy comes on the thread and says he avoided a stack allocation for perf and you can figure it out if you read the comments. And it goes on like that for a while. Code that is human readable often isn't the best performing at the machine level.

Anyway, I would take it more as a solid guideline for healthy code and less as a hill worth dying on.

Collapse
 
rossdrew profile image
Ross • Edited

assume that a given language is capable of clearly expressing any possible situation

No. I would say there's a completely separate rule for that. One that says you pick a language for a problem, not a language despite the problem. In this case the mistake was the wrong language for the problem, leading to you unable to express the problem, leading to comments needed to compensate so again...comments indicate a mistake made: bad language choice. Which is a huge problem in the industry where people write solutions in languages they are familiar with, rather than what is best for the solution.

I wouldn't die on any hill either. All rules have an exception but like I said before, we NEED to push into the grey area of a rule as much as we can before we accept it.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

All languages have to have been created by humans of limited vision and time. There may not exist a language that can clearly express a given situation.

Definitely if your code base has an over-comment/under-expression problem, it’s worth pursuing.

Thread Thread
 
rossdrew profile image
Ross

And that and exceptional exception to the rule in question ;)

Collapse
 
moopet profile image
Ben Sinclair

Business logic, links to API documentation, annotation (code-in-comments, ugh, but required for some frameworks), that sort of thing.

There's nothing wrong with comments, but if they're explaining something that should be obvious, go ahead and refactor it to be obvious.

Collapse
 
rossdrew profile image
Ross

All of that sounds more like API documentation than comments in code though.

Collapse
 
albindevs profile image
Albin Daniel Garcia

Well, I'm just a beginner. I've gone through some interesting github projects with really large code base, lots of files and I can tell that what stands out the most are the good descriptive comments that tell you what the file or function is, what it does, how it's used and so on.

Sure, the less comments the better. Good expressive code is essential for writing clean code. But comments are a faster way to help developers get a better understanding among lots of code.

If you don't write any comments at all, I think you're not considering other developers

Collapse
 
rossdrew profile image
Ross

But surely adding comments is placing more of a burden on developers. Now in addition to maintaining the code, there is a requirement to maintain comments.

Collapse
 
stereobooster profile image
stereobooster

What is the definition of "failure" in this context? It means something bad will happen or happened, right? But what? What are the consequences?

Collapse
 
rossdrew profile image
Ross

I would say a failure to write understandable code. A failure to write a intuitive abstraction of a given problem.

That could -for example- be failure

  • to gather enough requirements
  • in the understanding of requirements
  • of language choice, it being not expressive enough for the domain
  • in abilities in order to express the problem in an intuitive way
Collapse
 
rossdrew profile image
Ross

Referring to commented code as "overcooked" is interesting as that's what is actually happening in many cases.