Documentation in General
Everyone should hopefully already agree that documenting one's code is a good practice. Interfaces for libraries or self-contained modules should come with complete descriptions of how to use the interface itself, potential pitfalls, and so on. Internally, code should be sprinkled with comments that describe why certain algorithmic choices were made, how various design decisions were reached, and so on.
Now, documentation styles are as varied as programmers themselves - so I'm not going to get into any specific details of how to document code. That's a largely personal decision, and in my opinion it's something that one can easily decide will a little bit of careful thought and some common sense.
So instead, I'll be approaching a topic that is much more rarely discussed - when to do documentation.
The Prevalent Opinion
The conventional wisdom - and my own view for a long time - is that the best time to do documentation is right after you write the code. Everything is still fresh in your mind, the details of each decision are still clear, and generally things are still "warm." This seems like an ideal time to document code.
Sometimes, we might even want to pre-document code - that is, write documentation before any code is in place. This is typically a good idea when defining an interface for a library or some similarly contained module, where it is important that certain interface constraints and behaviours be met.
Pre-documentation is also a convenient way to explore new algorithms. First, write up a list of basic steps that the algorithm needs to perform, then slowly replace those comments with lines of code that accomplish what the comments indicated. Eventually, you finish all the replacements, and voila - working algorithm implementation (hopefully, anyways).
This is all well and good, but I think there's a better option.
The Bombshell
Here's my suggestion, stated simply: document code a long time after you write it. Put it off as long as practical within the constraints of your project.
Now why the hell would I say something so clearly insane? Procrastination is death, surely; with all that time between code and documentation, isn't it inevitable that something will fall through the cracks or just plain be remembered incorrectly?
My answer to this is it all depends on how careful you are during documentation. I suggest two passes: first, document the code the way you think you remember it works - or, even better, how it is supposed to work. Then, perform a code review.
During the code review, carefully analyze the code and make sure it lines up with the documentation. Remember, your memory is probably fuzzy here, so you'll have to think critically about each and every line of code to make sure that it (A) is correct and (B) matches the documentation.
I'm aware that this is going to be a weird concept for most people, because it runs so counter to the general expectations of how the mind works when coding and documenting. So let's go over the specific benefits of this method:
- You can get code done without worrying about documenting it until after the fact. This can come in handy when working on a tight deadline.
- This method works well with agile methodologies or general sprint-oriented development practices; do one sprint to write the code, then do a shorter sprint to document the oldest code which currently needs documentation.
- By allowing yourself to forget how the code works, you force yourself to be analytical and review the code as if you'd never seen it before. This is a tremendous benefit - the single major problem with reviewing code is that it is easy to ignore or skip things because you're too close to the system to see the flaws. Stepping back for a significant time alleviates this danger.
- If you have the staff, this is a great way to get everyone to understand critical central systems. For instance, if Joe writes a library that Bob and Frank will be using, Joe first writes the documentation, then hands off the completed package to Bob and Frank, who then perform the code review process. Now Bob and Frank are fully educated on how the module should work, and Joe gets the bonus of having a very carefully peer-reviewed chunk of code.
So there's my bit of programming heresy for the week. Now you can properly enjoy your procrastination, secure in the knowledge that it's actually making your work better!