Once I was in a situation where I was the responsible architect and we were discussing a series of refactoring that would lead to a better design.
One of the arguments against it was' then we need to adapt all the documentation we wrote'.
Which was one of my better moments, because I then deleted all extracts of source code in the documentation and instead of describing the implementation, we wrote down the principles that guided the implementation and the decisions we made.
Just saw the "self-descripting code" phrase: Isn't that rather more an idea than a reality in software industry? I just finished one of those self descriptive projects. A doc already exists: a requirement analysis doc, the problem domain analysis resulting into nice domain model, covered by tests, some 80%. To work this way is a pleasure for me. Unfortunatelly, my usual daily software engineer work is to deal with a mess. A mess improved by my "clever solution" still remains a mess that is hard to describe.
"Self-documenting code" was an ideal proposed back when. Code can certainly communicate more or less--I documented habits that tend to communicate more in Smalltalk Best Practice Patterns & Implementation Patterns.
I was finding myself torn on this one. I don't like writing documentation and I really don't like having to interpret the arcane meanderings of some half-baked lunatic from the mists of time...
Which will be me next week, reading the docs I wrote before I went on holiday a week ago...
Still, jokes aside, it's all about the storytelling for me.
When I ask questions like:
'Just why did someone make a decision to do it *that* way 5/10 years ago?'
or
'Why would someone have a constant 'ONE' for the value 1 that's only used once, but not have a constant 'EIGHT' for the value 8 that's also only used once?'
I want to be able to read a story about the Great Linting Insurrection of 2013 or the one about The Rogue Coder and their weird sense of humour.
Which is to say, at least make some sort of record about the who, what, why, where and when and so not have to rely on some sort of institutional knowledge being passed down through the ages.
That sort of thing just might as well be stories round a campfire to scare the junior devs.
I also want to hear those stories. My concern is that yeah you can write them down, but how will anyone ever find them. If a dev writes a doc in a forest with no readers should they have instead have just coded some more?
This is always my argument against things like wikis and intranets that are separate from the code repo -- you've got to know to go look somewhere specific and you've got to be able to find what you're looking for when you get there, and most of these systems are appalling for discoverability and searchability.
At work, we have a specific "How To" section in Confluence which is mostly a set of short "recipes" for DevOps and diagnostic stuff (including documenting hard to find settings pages in AWS, Google, Apple etc services!) but otherwise all documentation about code lives in the repo, with the code. Either a README for a folder tree of stuff or a comment block right there in the source next to the relevant code. Sure, it still gets out of sync sometimes, but we try to keep it as minimal as possible. Any "process" that is needed outside the code is more likely to become a script than a document anyway.
I largely (and respectfully) disagree. The primary objection to documentation and yours at various points in this post is that documentation and comments are often out-of-date. That is the problem that should be addressed, IMHO, rather than deprecating the value of comments and documentation. Code reviews, in my opinion, should carefully review comments as attentively as code to make sure they're in sync and that they communicate why this code was written if it is not completely clear from context.
One of the most important take-aways from John Ousterhout's classic book, A Philosophy of Software Design, is the importance and value he places on comments--including an entire chapter and numerous side bars.
I don't understand what you're disagreeing with. We seem to agree that communication is part of the job. You seem be less afraid than I am of the additional burden of keeping prose & code in sync. You seem to be ignoring my points about working to have less to communicate & communicating tactical details in code.
Thanks for your thoughtful reply. You wrote in that reply: " You seem to be ignoring my points about working to have less to communicate & communicating tactical details in code."
Not at all. This is where I disagree. Your code no matter how perfect it appears right now cannot communicate what good comments can: among other things: why you've chosen to do X and why you've chosen to do it this way. The whole "write better code to avoid writing comments" theme in your post implicitly communicates that there is something undesirable about writing docs and comments. There isn't or, at least, there shouldn't be. A good codebase contains good working code and ideally many useful comments, both of which are actively maintained.
Thanks for your reply. Each of your objections could be said about other aspects of development. God knows they've been said plenty about unit tests since you first started advocating for TDD! Commenting is a discipline, no different than coding, or writing tests. Which is why I think the topic we're discussing should be how to write good, useful comments, rather than how to avoid writing anything but the bare minimum.
Again, if you haven't read Ousterhout's book and his thinking on commenting, I think you'll find your time well spent. And perhaps influence your views. For me, he didn't so much influence my views as validate them, because I have long felt comments are as important and valuable as code.
I take it a step further than Ousterhout: I think that comments should be written *before* the code. Like writing tests first, this practice clarifies your thinking, helps with the design, and surfaces potential problems early. Then as you write your tests and code, you update the comments so that they match the implementation. The net result is that when you're done, you have working code, with tests, and enough commentary that anyone else coming after you can understand what you did and why without needing to read all your code.
One of the best-commented codebases (often used as the canonical example of excellent comments) is the Redis codebase. Look at the comments in this file, which I grabbed at random on Github.
I think you'll agree that someone coming new to the code or doing maintenance on it will be greatly helped by the presence of these high-quality, detailed comments. I just don't see how you can argue against them.
"and ideally many useful comments" -- that word 'useful' is doing a _lot_ of heavy lifting here...
If you find the need to explain "many" pieces of code, then I'd say those pieces of code are not "good" working code in the first place -- and the idea that "code reviews" should be about "reviewing comments .. to make sure they're in sync" is just creating unnecessary pain and delay, and slowing down the process. Why not pair instead, so that a separate asynchronous back-and-forth process (review) isn't even necessary?
Where the arrow represents a degree of separation but also a direct relationship.
So, if you change a bit of code, whether it be because of a bug, a refactor or a new feature, the expectation is that you then propagate said change through the relationships, change or remove the comment, update the documentation to reflect it etc etc.
The big *but* in all that of course is that people are lazy/under pressure/uninformed/etc and so don't always propagate the change - I'll do it tomorrow or that's so obvious everyone will get it and so on. Then we end up in an awful mess and have to spend hours reading code so we can understand why it's doing what it's doing.
You can always say, 'good' code doesn't need comments or documentation but you just have to read today's Work Chronicles to see how that goes.
I try and draw the line at using comments and documentation for when 'Business Logic' determines the reasoning behind things and for nothing else.
Note, Design and Test would go into that flow as well but then you start adding loops and so on but it's 10pm here and my brain is saying no to figuring it out for now.
Once I was in a situation where I was the responsible architect and we were discussing a series of refactoring that would lead to a better design.
One of the arguments against it was' then we need to adapt all the documentation we wrote'.
Which was one of my better moments, because I then deleted all extracts of source code in the documentation and instead of describing the implementation, we wrote down the principles that guided the implementation and the decisions we made.
The truth is in the code and in the test cases :)
Just saw the "self-descripting code" phrase: Isn't that rather more an idea than a reality in software industry? I just finished one of those self descriptive projects. A doc already exists: a requirement analysis doc, the problem domain analysis resulting into nice domain model, covered by tests, some 80%. To work this way is a pleasure for me. Unfortunatelly, my usual daily software engineer work is to deal with a mess. A mess improved by my "clever solution" still remains a mess that is hard to describe.
"Self-documenting code" was an ideal proposed back when. Code can certainly communicate more or less--I documented habits that tend to communicate more in Smalltalk Best Practice Patterns & Implementation Patterns.
Can't save you from cleverness, though.
I was finding myself torn on this one. I don't like writing documentation and I really don't like having to interpret the arcane meanderings of some half-baked lunatic from the mists of time...
Which will be me next week, reading the docs I wrote before I went on holiday a week ago...
Still, jokes aside, it's all about the storytelling for me.
When I ask questions like:
'Just why did someone make a decision to do it *that* way 5/10 years ago?'
or
'Why would someone have a constant 'ONE' for the value 1 that's only used once, but not have a constant 'EIGHT' for the value 8 that's also only used once?'
I want to be able to read a story about the Great Linting Insurrection of 2013 or the one about The Rogue Coder and their weird sense of humour.
Which is to say, at least make some sort of record about the who, what, why, where and when and so not have to rely on some sort of institutional knowledge being passed down through the ages.
That sort of thing just might as well be stories round a campfire to scare the junior devs.
I also want to hear those stories. My concern is that yeah you can write them down, but how will anyone ever find them. If a dev writes a doc in a forest with no readers should they have instead have just coded some more?
This is always my argument against things like wikis and intranets that are separate from the code repo -- you've got to know to go look somewhere specific and you've got to be able to find what you're looking for when you get there, and most of these systems are appalling for discoverability and searchability.
At work, we have a specific "How To" section in Confluence which is mostly a set of short "recipes" for DevOps and diagnostic stuff (including documenting hard to find settings pages in AWS, Google, Apple etc services!) but otherwise all documentation about code lives in the repo, with the code. Either a README for a folder tree of stuff or a comment block right there in the source next to the relevant code. Sure, it still gets out of sync sometimes, but we try to keep it as minimal as possible. Any "process" that is needed outside the code is more likely to become a script than a document anyway.
I largely (and respectfully) disagree. The primary objection to documentation and yours at various points in this post is that documentation and comments are often out-of-date. That is the problem that should be addressed, IMHO, rather than deprecating the value of comments and documentation. Code reviews, in my opinion, should carefully review comments as attentively as code to make sure they're in sync and that they communicate why this code was written if it is not completely clear from context.
One of the most important take-aways from John Ousterhout's classic book, A Philosophy of Software Design, is the importance and value he places on comments--including an entire chapter and numerous side bars.
I don't understand what you're disagreeing with. We seem to agree that communication is part of the job. You seem be less afraid than I am of the additional burden of keeping prose & code in sync. You seem to be ignoring my points about working to have less to communicate & communicating tactical details in code.
Thanks for your thoughtful reply. You wrote in that reply: " You seem to be ignoring my points about working to have less to communicate & communicating tactical details in code."
Not at all. This is where I disagree. Your code no matter how perfect it appears right now cannot communicate what good comments can: among other things: why you've chosen to do X and why you've chosen to do it this way. The whole "write better code to avoid writing comments" theme in your post implicitly communicates that there is something undesirable about writing docs and comments. There isn't or, at least, there shouldn't be. A good codebase contains good working code and ideally many useful comments, both of which are actively maintained.
There *are* things undesirable about docs & comments:
* Redundancy
* Cost of maintenance
* Written from the perspective of the writer not the reader
By all means, communicate important things not easily readable from the code & tests. But no more.
Thanks for your reply. Each of your objections could be said about other aspects of development. God knows they've been said plenty about unit tests since you first started advocating for TDD! Commenting is a discipline, no different than coding, or writing tests. Which is why I think the topic we're discussing should be how to write good, useful comments, rather than how to avoid writing anything but the bare minimum.
Again, if you haven't read Ousterhout's book and his thinking on commenting, I think you'll find your time well spent. And perhaps influence your views. For me, he didn't so much influence my views as validate them, because I have long felt comments are as important and valuable as code.
I take it a step further than Ousterhout: I think that comments should be written *before* the code. Like writing tests first, this practice clarifies your thinking, helps with the design, and surfaces potential problems early. Then as you write your tests and code, you update the comments so that they match the implementation. The net result is that when you're done, you have working code, with tests, and enough commentary that anyone else coming after you can understand what you did and why without needing to read all your code.
One of the best-commented codebases (often used as the canonical example of excellent comments) is the Redis codebase. Look at the comments in this file, which I grabbed at random on Github.
https://github.com/redis/redis/blob/unstable/src/ae_evport.c
I think you'll agree that someone coming new to the code or doing maintenance on it will be greatly helped by the presence of these high-quality, detailed comments. I just don't see how you can argue against them.
"and ideally many useful comments" -- that word 'useful' is doing a _lot_ of heavy lifting here...
If you find the need to explain "many" pieces of code, then I'd say those pieces of code are not "good" working code in the first place -- and the idea that "code reviews" should be about "reviewing comments .. to make sure they're in sync" is just creating unnecessary pain and delay, and slowing down the process. Why not pair instead, so that a separate asynchronous back-and-forth process (review) isn't even necessary?
Thanks for your thoughtful comment. Sure, pair programming is an excellent solution to the question of what and how to document.
I see it as something along these lines:
Code -> Comments -> Documentation
Where the arrow represents a degree of separation but also a direct relationship.
So, if you change a bit of code, whether it be because of a bug, a refactor or a new feature, the expectation is that you then propagate said change through the relationships, change or remove the comment, update the documentation to reflect it etc etc.
The big *but* in all that of course is that people are lazy/under pressure/uninformed/etc and so don't always propagate the change - I'll do it tomorrow or that's so obvious everyone will get it and so on. Then we end up in an awful mess and have to spend hours reading code so we can understand why it's doing what it's doing.
You can always say, 'good' code doesn't need comments or documentation but you just have to read today's Work Chronicles to see how that goes.
I try and draw the line at using comments and documentation for when 'Business Logic' determines the reasoning behind things and for nothing else.
Note, Design and Test would go into that flow as well but then you start adding loops and so on but it's 10pm here and my brain is saying no to figuring it out for now.
Some forms of documentation that I consider useful:
→ Function/method-level comments like those of JSDoc/JavaDoc.
However they can be an enormous waste, to me the "good" ones are like those described in https://ieeexplore.ieee.org/document/8880061.
→High-level, small diagrams:
- Explaning how multiple services communicate at the "network" level.
- Some visual aids for helping understand business domain concepts.
→README files.