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).
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.
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.
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
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"?
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 */consttraverseGraph=()=>{}
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.
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.
Children's museum worker turned software engineer with a lot of hard work and a great bootcamp experience. Currently making good things great at Untappd.
💯 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.
Children's museum worker turned software engineer with a lot of hard work and a great bootcamp experience. Currently making good things great at Untappd.
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.
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".
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
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).
Surely if you need a "why", then there is a failure somewhere.
Sarcasm? (Poe's Law)
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?
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 aFuelessWarehouse
. 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.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.
In this case it's just organisation, it's called using a
memoryOptimisedDijkstra()
and no comment necessary.like this?
How did you get from
to
^ 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.This one is still valid use-case.
No, it isn't. Even this hack is better than a comment
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
@stereobooster
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
It seems we can agree on this
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.
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.
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.
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.
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.
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.
💯 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.
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
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".