I recently spoke with Nicolai Parlog, author of Comment Your F**king Code. After his article struck a chord with our readers, we reached out to speak a bit more about agile, clean code, and team collaboration.
Thanks so much for taking the time to talk today, I really appreciate it.
Sure, no problem.
You’ve been an MVB for a while, and your article “Comment Your F**king Code” has been getting some responses both on our site and your blog.
NP: It wasn’t a big surprise. I wouldn’t say I planned it, because I was really flustered when I wrote it, but I knew it would happen. But I was surprised by how well the different discussions went. There were very few people trying to pick fights and most comments were well-conceived. Most were discussing the topic even if they held different opinions.
Could you tell us a bit about your experience and area of expertise?
I’ve actually only been working as a professional software developer for four years now, and studied computer science at Dortmund in Germany. In all my projects, be it at university or in my job, I always felt that code quality could’ve been better, and code documentation could’ve been way better. I felt like I had to do way more work than necessary to understand something that was supposed to be simple. Like some API was straight-forward to the author when the wrote it, but now a year later, two years later, five years later, it’s like some arcane mystery. Even with tests it’s not easy to find out what the author was thinking when writing the code.
So what should good comments really try and communicate to future developers?
That’s the toughest question that arises from the article and the following conversations. Before I wrote it, I felt I had a good idea of how to answer that question. Then with the discourse that ensued, I felt less sure. Last Friday I gathered my coworkers, we discussed it as well, and it turns out it’s a tough question to answer. This problem has a lot of dimensions. For example, I think that comments are always at risk of aging or getting out-of-date when developers don’t update them. They’re an investment that shouldn’t be taken lightly.
Personally I am very guilty of over-documenting my private code, I admit that. It’s not healthy the way I do it. What’s most important is that each team decides what they want to do, and then really stick to it and update comments as they go.
As far as good comments go, when I use a library, I enjoy it when there’s good Javadoc. It helps me immensly if there’s a proper comment that tells me what I need, like pre-conditions or post-conditions, basically everything that’s described in Effective Java by Joshua Bloch. It goes into great detail by our standards. When I call any method from the JDK, all the documentation is there. So if we can get comments as perfect as the JDKs for free that would be the way to go. But since they aren’t free we have to decide where or when to put them.
You mentioned earlier you discussed with your team about this topic. Can you walk us through that process of getting everyone together and coming to a consensus?
Well every Friday we grab a beer and hang out so getting the team together was easy. And as you saw from the article it’s not hard get them talking about the topic. The discussions online and in-person were almost the same. You have people who say that clean code doesn’t need comments, you have people who have been burned by not having commented code, and you have people who have been burned by having bad comments. So then you have align all of that, and we try to identify not so much how a good comment is made, but when and how to add a comment.
Now in Effective Java and Clean Code, they both say you should document public APIs, but I think that the term public is a bit misleading. I am working in a large project and the public API our customers call is very small. But if I have to use code that someone wrote five years ago now, that is, to me, very similar to the principles of an API.
So when we write code to address a problem like connecting to some web service, which will be used throughout the product, it’s an API that your team will be using. It’s not public but it needs to be well-documented so people know how to use it. We want more documentation on more stable parts of the program. On others, which the customer really cares about and business people can require to change any minute, there’s more wasted time when comments have to be updated continously. So we decide what code is more stable so the effort of rewriting existing comments is less wasted.
So the demands of business and customers impact that a lot, and comments are best for anything that will be stable and used frequently.
Yes, but it’s still a multidimensional problem. There are different ways to go and to measure how useful a comment can be. Another way could be to comment later after the code has been in use for a year. Then you really know which parts are often used and you can sit down and document it then as a learning experience. I also think that bigger teams would require more documentation, because your five-person team can keep the flow of information pretty tight, and everyone knows what’s going on. A team of fifteen or twenty people will find it harder to get this knowledge to go around, and commenting would be more worthwhile.
Were there any prevalent arguments you wanted to respond to, or were there any comments that made you change your thoughts?
At least one of the claims I made was perfectly wrong. I said that mutability is hard to test clearly. Turns out that’s wrong. There’s a library called Mutability Detector (thanks to Sean Reilly for pointing it out) where a simple assertImmutable(MyClass.class) tests all the crazy details required for true immutability.
I know it’s best to write clean code, I do it best I can, and I know you need readable tests, it’s worth the time to invest it. My point is, we spend all this time reading code, and putting in an extra 2% effort to add documentation will add some value. I think that many tests are not perfectly written, and until I get told otherwise I will assume my tests aren’t perfectly written. So I doubt their effectiveness for documentation.
For example, I’ve been writing my own collection implementations, using Guava to test them. So I know that Guava generates about 500 unit tests for a List, for example.ow is anyone going to reverse engineer anything by reading those tests? They’re all valuable but it’s not the easiest documentation.
Up to here I didn’t mention clean code because I didn’t want to sidetrack myself, but I don’t think clean code itself is the answer. The value of any abstraction is diminished by the time it takes me to understand it. Good documentation can reduce the amount of time I put in, and that will be the focus of a follow-up piece I am working on.
Anything else you’d like to add?
One thing I soon realized is that we do not all agree on what a comment is. Some people figured API documentation (like Javadoc) aren't comments but documentation. Whoever is right, when I talk about comments I expressly include them.
What we did not talk about are comments to clarify intent, to document workarounds and other non-contract comments. I am all in favor of them but no mumbling - they have to contain essential information.
One other thing is that the degree of documentation does not have to be consistent throughout a project. Maybe for API-like classes you want to go full out and document everything. In other classes it might be enough to explain the type's central abstraction and nothing more.