Should comments in code be considered failures in coding?

github logo ・1 min read

Uncle bob says:

  • Should code be written in a way that's expressive enough on it's own?
  • If you disagree, what are your thoughts on keeping comments up to date with changes?
  • Is there a grey area? Examples?
twitter logo DISCUSS (81)
markdown guide
 

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).

 

💯 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.

 

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.

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.

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.

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

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

Code review. Come to a consensus.

20 years a developer. I've never had a comment teach me anything about well written code.

But you agree that different people have different opinions on the readability of the code? And you strive for understanding in the team and you can reach it in the team, but then somebody new comes to the team and you may need to reconsider readability of the code. As well when people do review it is not done by the whole team, but only by the part of the team (depends on the size of the team), which means that part of the team may not consider code easy to read.

Different people have different opinions but there is a middle ground and we strive for that. It shouldn't be acceptable to say "I wrote unreadable code so I wrote a comment to explain it".

 

Surely if you need a "why", then there is a failure somewhere.

 

What?!?

Why is far more important than "how". And you cannot convey this "why" part in code, its semantics is not fit for this.

"Why" includes a lot of things - what's the reason for this code to even exist, why it's making all those assumptions about the input data, why this particular optimisation is chosen and what extern performance constraints were taken into consideration.

There is always far more of the "why" part of the story than the actual code. Code is trivial and immaterial, while "why" is all that matters in a large scale.

"why" is all that matters in a large scale.

Very rarely has the why mattered unless you are doing something very silly or something very specialised. One case is common and is what we are talking about, the other is the exception that proves the rule.

Code is trivial and immaterial, while

I find that kind of attitude is what leads to bad code excused by comments. Code isn't important, comments are is just a crazy, dangerous notion to me.

Very rarely has the why mattered unless you are doing something very silly or something very specialised.

How comes? You always start with "why?". Pardon my tautology, but "why?" is exactly why you're writing your code in the first place. How can you argue it's not really that important if it's the only thing that's really important and code is only secondary to it.

One case is common and is what we are talking about, the other is the exception that proves the rule.

I cannot really think of a single case where "why" is less important than all of the "how" code. Not a single one. Maybe, training toy problems that are designed solely to practice coding skills are a bit of an exception, but in actual practice you won't find a single case like this.

I find that kind of attitude is what leads to bad code excused by comments.

All code is bad. By definition. You must avoid it as much as possible. The less code - the better.

And having proper literate comments is a good way to get rid of code.

 

@stereobooster

would you prefer if I put an explanation of the term "frame" in the comment or not?

Not. Remember we are talking about comments in code here, not API documentation. This may be a case for explaining in API doc (Javadoc for example) what a method expects or what a class does but "in code"?

So it's ok to put comments on the top of a function, you are arguing with comments in the body of a function, right?

Yes, code comments. Any comments in the code block or any comments which explain specific low level implementations in the code block.

To be fair most of my examples can be put in the top of a function, including definitions, explanation of business rules, explanation of code optimizations, etc. So I don't see any contradiction anymore

/* This is classical implementation of Dijkstra algorithm, except that we skip allocation of heap in ... which makes it a bit slower, but take less memory */
const traverseGraph = () => {}

It seems we can agree on this

 

Not at all. If you feel like you need to explain something. It's possible it's not acting in an intuitive way and some failure in method has occurred.

What if you need to explain business rules? For example, we can't store fuel in this type of warehouse, this is why we need to do this check..

What if you explain some unexpected behaviour in other system? For example, we need to put pause here because our hardware is not able to proceed signals so fast.

What if you need to explain some unobvious code trick? For example, we use modified version of original Dijkstra algorithm, it is a bit slower, but takes less memory.

It is not just "why", sometimes it is "what". For example, we write a small library for visualization. We use the term "frame" there. Can you guess what is it? If you will search the internet for "frame programming" it will give you "stack frame", "frames per second". The term "frame" in my case comes from "The Grammar of Graphics" (similar to Pandas DataFrame), would you prefer if I put an explanation of the term "frame" in the comment or not?

we can't store fuel in this type of warehouse, this is why we need to do this check

Then you use structures in your paradigm(s) that express this in an intuitive way. For example in OOP we extend (or compose I guess) Warehouse with a FuelessWarehouse. Contrived example but still, better than comments and doesn't rely on someone to read, follow and maintain comments and avoids issues caused by out of date comments.

we need to put pause here because our hardware is not able to proceed signals so fast

Then again you express it using your paradigm of choice by using threads/futures/objects that convey this in a verifiable way and if that fails, a test which describes the behaviour then it can't simply be ignored.

we use modified version of original Dijkstra algorithm, it is a bit slower, but takes less memory.

In this case it's just organisation, it's called using a memoryOptimisedDijkstra() and no comment necessary.

doubleCheckIfThisFuelBecauseWeCantStoreItWithoutFireAlarm();

putPauseBecauseBugInZeexel2000MA();

aBitSlowerButMemoryOptimisedDijkstraBecauseWeSkipHeapAllocation();

like this?

How did you get from

For example in OOP we extend (or compose I guess) Warehouse with a FuelessWarehouse

to

doubleCheckIfThisFuelBecauseWeCantStoreItWithoutFireAlarm()

fun storeFuel(Item item, Warehouse warehouse) throws FireSafetyException{
 if (item instanceOf Fuel && !warehouse.hasFireAlarm()){
   throw FireSafetyException("Not equiped for fire safety")
 }
}

^ where is the comment required?

Example with business rules. I agree with you here.

Example with code trick (memoryOptimisedDijkstra) we agreed that we can put comment in the top of the function, which is out of your question because you ask only about comments iniside the block.

What if you explain some unexpected behaviour in other system? For example, we need to put pause here because our hardware is not able to proceed signals so fast.

This one is still valid use-case.

No, it isn't. Even this hack is better than a comment

fun doSomething(Operation o, Evnironment e){
  if (e.isSlow(){
     slowO =  SlowHardwareDelayOperationFactory.create(o)
     slowO.perform();
  }else{
     o.perform();
  }
}

because
a: it is verifiable, we can write a test to say if the environment is slow we add a delay, unlike a comment
b: it is self documenting
c: it's reusable, unlike a comment
d: if we no longer need the delay and remove it, there's no comment to clean up

 

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

 

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.

 

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.

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.

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".

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.

Then you are not here to protest the use of comments in how most of the world are programming, it's to suggested that most of the world are just programming completely wrongly. Despite most of the world abandoning your method as unmaintainable 30 years ago.

Literate programming was useful when domains and solutions became too much for weak languages. Maybe even still useful for horrible languages like Perl. Languages have evolved so towards writing expressive solutions in code which is runnable, testable and therefore verifiable.

Again, you're suggesting that the language can somehow express the "why" part. Sorry, but it cannot. No way. Even the most beautiful DSL would not ever be able to convey all that information.

And yes, most of the programmers are doing it wrong. Why would it even surprise you?

Just try to reflect on a fact that Literate Haskell exist and is quite popular. Or have a look at my example back in this thread - my language there is extremely high level, and yet it works much better when used in a literate code. Not to mention other literate systems that are very popular along with some very high level languages - Jupyter notebooks, for example, or Pweave.

No, I'm suggesting that the why part is irrelevant unless you have did something abnormally. If you drink tea, you don't need to explain why. If you drink horse piss, you can expect that people will want to know why.

Just try to reflect on a fact that Literate Haskell

Strange that you are strongly against small functions but use Haskell as an example in which small functions are a core part of the language.

systems that are very popular [...] Jupyter notebooks, for example, or Pweave

So popular in fact that in 20 years in the industry I've never met someone outside academia that use them.

If you drink tea, you don't need to explain why

If it takes few man-months and hundreds of thousands of $s to drink that tea, you'd better have a very good reason, very eloquently explained.

Writing code is a bad thing to do. You must always justify it.

as an example in which small functions are a core part of the language

Nope, there are very frequent cases where you'll have a large pattern matching, probably spanning across few screens.

So popular in fact that in 20 years in the industry I've never met someone outside academia that use them.

Please stop referring to your 20 years, or I'll start suspecting they're 1 year repeated 20 times.

I've been around for far longer, seen things. I perfectly understand what kind of industry you're talking about, and it's a very bad example. Nobody should ever try to reproduce methods common in such an industry. There are places in this industry where people do things in a much more organised way.

Please stop referring to your 20 years, or I'll start suspecting they're 1 year repeated 20 times.

Yet you can repeat your mantra 40 times. Everything is wrong except the way you do it, got it. You disagree with everything, nothing productive is being said and everything unproductive is being repeated.

It's not a "mantra", it's an objective observation. Your views of how this industry works are very evidently limited. You can get this kind of a tunnel vision only if you stick to something extremely repetitive and dull.

Tunnel vision .. if you stick to something extremely repetitive and dull

from the guy selling a paradigm invented in 1983 and largely abandoned in 1984.

Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

Again, how many Jupyter notebook users are out there? Your OOPish religion is a pile of crap, and you're way too deep in your zealotry to be able to admit it.

Go sell literate programming somewhere else. Nobody cares about your insulting, arrogant, ancient views.

Once again, hundreds of thousands (at the very least) of the Jupyter users would laugh in your face.

Just have a courage to admit that you simply don't know enough to be able to reason about code quality and development practices. That'd be sufficient. And then start learning from scratch. And never again touch anything produced by this "uncle bob" unhinged preacher.

Also, please avoid having any strong opinions until you can reach the level of code quality of, say, TeX. As of Aug 2019, it have 8 bugs found and fixed. Good luck getting to this level of quality with this "clean code" religion of yours.

Whenever you are finished repeating yourself, feel free to go find a discussion relevant to your dead paradigm.

So you're admitting that you're deaf to all the rational arguments? That's exactly what zealotry is. That's exactly why the rest of the industry hates everyone who dares to even mention uncle bob.

zealotry: fanatical and uncompromising pursuit of religious, political, or other ideals; fanaticism.

Ideas such as literate programming.

Nobody is defending Uncle Bob. Asking you not to be insulting to and about everyone and anyone who doesn't share your idea that the solution to all programming problems is a paradigm rejected by the industry 30 years ago is NOT defending a single person.
Nobody is being "fanatical" or "uncompromising" about the subject at hand, which is the value of comments in modern code. We (that is, everyone but you) are in fact having a polite discussion where I -as the proposer of said topic- am playing devils advocate to suggestions to the contrary. The only fanaticism I see and the only one being uncompromising is the one calling people names and strongly insinuating everyone but themselves is stupid, uneducated and/or backwards. The one who is quite clearly "fanatic" and "uncompromising" about a hatred of any and all Uncle Bobs ideas and of LP.

Jupyter users would laugh in your face.

So you're admitting that you're deaf to all the rational arguments?

you simply don't know enough to be able to reason about code quality and development practices

this "uncle bob" unhinged preacher.

please avoid having any strong opinions until you can reach the level of code quality of

you're all beyond any redemption

Looks like you always worked with some truly awful programmers.

This coding part does not deserve even a tiniest fraction of attention it's getting

So if you could stop acting like a petulant child, we've heard your arguments. They are off topic, uninterested and the approach you are selling is dead! Feel free to consider us scolded and give up.

I mean, you've clearly been having this argument for years with zero success, give it up.

is a paradigm rejected by the industry 30 years ago

Ok, I got it, you enjoy being an obnoxious liar. It suits you, actually.

and the approach you are selling is dead

Do you really think that your incompetent opinion on this topic matters? Really? You're ignorant, and it's your choice. You can either try to learn, or stay ignorant.

And yes, you're exactly a very convincing example of why people hate uncle bob zealots.

Do you really think that your incompetent opinion on this topic matters?

Matters enough for you to spend three days arguing with me about it.

uncle bob zealots.

Once again. Never once defended Bob in any way and that makes me a zealot.

Give. Up. Griffiths.

Matters enough for you to spend three days arguing with me about it.

You're a lost cause, as I stated pretty much straight away that uncle bob fans are beyond any hope. I'm providing arguments for passers by who might otherwise get swayed by your destructive preaching.

Never once defended Bob in any way and that makes me a zealot.

You're defending his position on in-line comments - that's sufficient, given that it's pretty much a core tenet of his religion. If you walk like a clean code zealot and quack like a clean code zealot, you're a clean code zealot by all practical means.

uncle bob fans are beyond any hope

Third time: I'm not an uncle bob fanatic or even a fan. Never once even slightly indicated that might be the case. I proposed one of his assertions as a discussion to which you have thrown yourself at.

your destructive preaching.

Haven't preached once. You however...

You're defending his position on in-line comments

I'm playing devils advocate with a single assertion to promote healthy, polite discussion.

If you walk like a clean code zealot and quack like a clean code zealot, you're a clean code zealot by all practical means.

Appear to lightly agree with something == zealot. Yes, exactly the same thing. For a mathematician your logic is shocking. I can see why you need so many comments in your code, because you're clearly incapable of anything but typing and endless stream of completely illogical tripe.

I wont be responding to anymore of your nonsensical rubbish.

I proposed one of his assertions as a discussion to which you have thrown yourself at.

Not just one, but the most controversial one, which also happens to be the core belief of his entire "clean code" system. Everything else is immaterial in comparison.

Haven't preached once.

You keep insisting on a lie that in-line comments get stale in no time, because developers are lazy. And you propose a solution of having all that documentation elsewhere, because somehow magically it won't get stale this way. Which is 100% identical to all the arguments of uncle bob and his unhinged followers. You walk like them, you quack like them, you're one of them. By definition. No matter what your motivation for taking this position is.

I'm playing devils advocate with a single assertion to promote healthy, polite discussion.

And you just demonstrated your own project that practices exactly what you preach here. So much for a devils advocate.

Also, what "healthy discussion" you're talking about, if you dismiss all the arguments of why the opposite approach works better as "trust me, I have 20 years of experience, so take my word that it's not how the industry works, it was abandoned 30 years ago, and don't you even dare to argue, because I have 20 years of experience" (and then repeat it a dozen of times more, in case if someone missed the super important fact that you have 20 years of experience). The funny thing here is that you honestly believe that you even have sufficient credibility to speak for the entire industry. Your attitude to arguments is as far from anything "healthy" as possible, so don't be surprised when people treat you like a troll.

Appear to lightly agree with something == zealot. Yes, exactly the same thing.

Not just "something", but the defining tenet of the religious system. Believing in the core beliefs of a religion makes you a follower. And the fact that you find this solid logic "shocking" is pretty much consistent with everything else - your OOP zealotry, your lack of experience, your misguided manners.

 

Like many of the comments, you are describing comments on problem code. To me that describes a mistake in language choice or expression of the problem in code. Like many of the comments you also seem to be arguing that comments do indicate mistakes but that sometimes it's acceptable. Suggesting that

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

Is true.

 

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.

 

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.

 

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.

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.

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.

This is what religious fanatics say when they're cornered. Uncle bob zealots are the worst of the worst, you're all beyond any redemption...

 

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.

 

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.

 

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.

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.

"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.

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.

Looks like you always worked with some truly awful programmers.

My criteria for a good programmer is not any technical competency, not some arcane CS knowledge, etc. The best programmers I met are good writers.

Once again, you cannot keep documentation up to date. Only if your code and your documentation are the same they can be kept in sync. Then any pull request is trivial to verify - you see all the documentation context right in front of you, and if the code change proposed is going against what is said in the text, it's obvious immediately.

Well, point is we disagree at a very fundamental level. I asked about comments in how people code, your complaint was that everyone but you does it wrong, called Uncle Bob a "buffoon" and everyone I've ever worked with for 20 years a "truly awful programmer".

So keep preaching, nobody is jumping on such a bitter train.

your complaint was that everyone but you does it wrong

Lol. Do you have any idea of how many people are using, say, Jupyter notebooks?

called Uncle Bob a "buffoon"

And I'm not alone. Any sane person looks at uncle bob with nothing more than a plain disgust.

and everyone I've ever worked with for 20 years a "truly awful programmer"

Again, it happens in certain industries. Good programmers try to stay away from such places. Birds of feather, and so on.

And yes, I have a very good reason to believe that anyone who takes uncle bob bullshit seriously is lost forever, and I'd do whatever I can to never work with such toxic, destructive people.

 

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

Yes, and this is very difficult. I've seen very senior developers struggle to do this. My theory is that writing expressive code is a challenge more similar to poetry than algebra, and programmers tend to not study poetry.

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

I do agree with this, and a significant part of what I do in code reviews is showing developers how to refactor into more expressive code. The most effective form of coaching I've found is refactoring code that someone is convinced can only be understood with comments. Ironically, the comments usually indicate how the code should be refactored.

Is there a grey area? Examples?

I don't believe there is a grey area, as being able to express complex ideas simply in code is core to programming, and comments are a crutch that prevents you from learning that core skill. It's a bit like over-cooking food: you can eat food that's overcooked, but you'll never learn truly learn how to cook if you allow yourself to serve over-cook food. At some point, you will have to draw a line and say "I will not overcook food," and then work hard to achieve that aspiration.

When I give code reviews, rather than just say, "No comments allowed," I say, "Watch me refactor this so that the comments are not necessary." Without someone to provide that in-the-moment contextual coaching, however, simply telling someone "comments are bad so never use them" rarely accomplishes anything more than having the comments deleted without the code being refactored, which is generally a worse situation than leaving the comments in.

 

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

 

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.

 

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.

 

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.

 

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.

 

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.

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

 

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

 

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.

 

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.

 

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

 

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

 

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
Classic DEV Post from Jan 18

Sh*tpost: can we stop saying "syntactic sugar"?

What does it actually mean? you're not helping!

Ross profile image
Freedom to be concise is is too often an excuse to be unclear