söndag 30 mars 2008

Dedefending my case: Stop documenting your code!

Here is my response to Peters post - Do comment code!:

First off, I think it's okey to be critical, you should not take anything for granted, and of course we all have our own ways of programming. My post was more of a tip based on my own experience from working in a larger team with no/little code documentation.
Commenting code isn’t as much about pinning down knowledge, as it is communication. And when it comes to communication, redundancy is almost never a problem :)
Commenting code is communication, but you are communicating knowledge. The same knowledge is always communicated through the code. If you find it hard to "read" the code, then, in my own experience, the code is not well written and/or formatted. Make sure you have a coding policy stating how you should write code so that all code looks the same and can be easily "parsed by your brain". It's amazing how much easier it is to read code that is well written and formatted.

I'm not saying you should avoid all documentation, but documenting every class and function is always redundant if the documentation doesn't state anything new. You should always strive for having code that is easy to read, before putting comments around everything you do.
And another thing, without documentation, I might misunderstand the code I’m reading and think that I find defects or suboptimal solutions.
That's true. Of course you can have comments here saying "don't use this function this or that way", but perhaps there is another way of writing the function so that it can't be used incorrectly? If you write a method and document in the header that this function should only be used if some requirements are met, then I guarantee you that this function sooner or less will be misused. Make sure you add requirement checks (for example assertions) in the beginning of the function breaking the program, so that you crash early if someone make such misstates. But always strive for writing code that is impossible to use incorrectly.
And then there’s the case with APIs that you don’t have the code to… Ok ok, thats another story.
If you are shipping your code to another company, or group of programmers, then you always need to communicate what the code does, because the code you shipped is persistent and will not change. Thus, the comments you write will always be correct (if being correct when shipped). And if you don't ship along your implementation, then of course you need to document your code, but more importantly, document your project as a whole. Do this by describing how it should be used and what the subparts of the project does and how they communicate with each other. Focus on the big picture.
But hey, you can’t possibly mean that I shouldn’t document my Assembly code, do you? Super haxxor might read and understand ASM as I understand English, but the vast majority don’t.
Well, if the super haxxor wrote the code then he or she will in most cases be the only one reading it and than you don't need documentation. If the assembly code is only a small part of the project which is written in another language (say C++), extract the assembly code and put it in it's own function describing what it does. By doing so, you will also make the code more easy to test and validate! A better question might be, do you really need assembly code?
Saying that documenting/commenting code is wrong, is saying ‘I don’t care if other people are able to read my code, and if they don’t understand their lazy and dumb’. And thats lazy and dumb :-)
I'm saying that if you write your code so that a follows a well written coding policy, you will not have any problems with reading the code. If you feel that some code you have written needs to be documented, stop a second and think about it. Is there another way of formatting the code so that it's easier to read? What if I extract a part of this function as a new function, giving that function a good name, would that help? What about using coding policies for variable naming conventions? Adding prefixes such as m_ for member, p_ for parameter and l_ for local will for example quickly let you identify the scope of a variable.

Here are some final notes from me:
  • If you are working on a larger project, then your comments will become deprecated sooner or less. You must alway be aware of the fact that any code you write now will probably be changed in the future (no code is perfect).
  • Always strive for as little code as possible. The more code you have, the more code you need to maintain. The same goes for comments.
  • Write comments in unclear situations, but don't write trivial comments. Instead, define a good coding policy and start writing "easy to read" code!

2 kommentarer:

Gustaf Nilsson sa...

Nice post! I agree on most of your thoughts, some comments though..

* Dividing your code blocks with commented "labels" seems pretty harmless, just to show a division of concerns. Though, if the method shouldn't be too large.

* Coding conventions is basically just a set of regexp rules. It provides a bit more readable code, but I think manual inspection meetings are a good complement for this. For example (in C#) your boss could have hired a crazy functional programmer that rather write lambda-calculus than regular OO style. Traditional coding conventions would not cover this.

* Statical analysis (i.e. code metrics) could be another complement, i.e. a McCabe Complexity value above 40 would indicate that something fishy is going on. If you reduce complexity you can remove unneccesary comments as well

* Algorithms should be well encapsulated in classes/modules and well commented, I think. Dynamic algorithms can be really tricky, but hey even old Dijkstra's algorithm is not trivial.. :)

* Business logic should probably be written in a "higher level language" (interal/external DSL, workflow, BPEL, etc..) because business logic tends to change in a higher frequence than other code..

* I should really start my own blog.. ;)

Christian Genne sa...

Thank u! Nice comments :) Some response to your comments:

* Labeling your code is not wrong, it's actually a nice way of using syntax highlighting to divide the code. But in most cases you can simply extract the labeled blocks into new functions, can't you?

* Coding conventions have some specific pros according to me: 1) No one will get annoyed because some code is formatted ugly according to them. 2) Code will look the same all over, and thus you don't get the feeling of code being written by different independent coders. 3) When you get used to a convention, you will understand the code faster!

I actually do think that many coding conventions (CCs) in larger projects cover if you should write your code in lambda- or OO-style. Of course, CCs change over time (suddenly you could write lambda-functions in C#!), but you also need to respect them. Don't write lambda-style if the CC doesn't state you should, because some of the programmers might not be used to this style of programming.

And as you said, coding conventions are just a set of regular expressions, which is good because then you can write a program that analyzes your code to make sure it follows the rules! :)

* Statical analysis is a very nice complement, but then you need to know what code complexity really means :)

* I agree that you should comment algorithms. Even if you put them in there own functions describing what they do, you should write comments on how they work. Actually, in all cases where your code is hard to get, and there is no way to refactor it, you should add comments!

* I don't have so much more to say about buisiness-logic coding, you already said everything that is needed to know :)

* Yes, you really should :)