I spent a good part of this afternoon in a planning meeting with my assistant lead developers, Alex and Jarek. We hashed out a lot of details for the new year, not least of all, ground rules for adopting libraries.
See, we've burned a lot of man-hours in the past on learning libraries. One of our projects ultimately met its demise because of an infamous XML parsing library (which will remained unnamed to protect the guilty developers involved) – our project's developer had to put in somewhere around 6 months of work to learn the library. Another of our developers, working on a completely different project, had to invest the same amount of time into learning the same library.
When you're running a software startup that relies on six-hour-a-week interns, that's time you can't afford to burn.
As we recounted those facts at the meeting earlier today, I had a revelation. “Learning a library is a non-transferable investment.”
“We need to set a cap on how long we can spend on that sort of thing,” Jarek mused.
“I'd say one month,” added Alex. “For a typical intern's schedule, that's what, 20 hours?”
We all agreed that was reasonable, but that brought with it a new requirement for adoption of any library: it had to have well-written documentation. API auto-docs don't count, we decided. “It's the least useful form of documentation,” Alex observed. “You usually need to know how to do something specific, not so much how many arguments a function takes.”
We began scrutinizing our list of libraries, dropping a couple, and picking up a few more. The meeting drifted onto other topics, finally coming full circle as we approached the topic of our own documentation standards.
“Perhaps we can establish a list of topics that should always be covered,” suggested Alex, nodding to some of our existing docs up on the computer screen. “Like, what all is the library capable of doing?”
“For every â€˜what', we need a â€˜how',” I added.
That's when we collectively realized something: a complete project had to answer all the same questions our teachers used to ask us in grade school English: Who, What, Where, When, Why, and How.
When you download a library or view a repository, the first thing you're going to look for is the README. Not finding one is pretty disconcerting. I've read quite a few guides on writing a good README, but we managed to boil it down to answering four of those questions:
What: Your README is the first place people will look for a description of your project. What goal are you trying to accomplish? What makes your project so special? This question is answered more in depth elsewhere, but the README should cover it in brief.
Who: This is about so much more than getting credit for your work! Every project needs a person or group who is ultimately responsible for calling the shots. Answering this question includes providing information for contacting the person in charge. How are bugs files, changes submitted, and features requested?
Where: Users will encounter your project in many forms, and not all of them are terribly useful. Perhaps they picked up an old tarball of the source code, acquired a compiled binary, or found an out-of-date repository. The README should describe the official location for finding the latest copy of the source code, as well as links to more information about the project and/or its maintainers.
When: Your users need to know when changes were made, and when different versions were released. As end-users, MousePaw Media frequently uses this information for determining the minimum version of a library, tool, or application that we can use. This type of information is usually tucked into a separate CHANGELOG file, but I typically consider it part of the “README bundle”.
I've seen entirely too many projects where the full extent of the documentation was a pile of auto-generated technobabble. News flash: API docs are almost never useful to anyone but the project developers!
As I explained to someone once, most API documentation is like teaching someone how to use a toaster by explaining the electrical specifications of the heating element. Documentation is asynchronous, so you're not seeing the user melting down on the other side: “I don't CARE about the voltage of the stupid heating element! I JUST WANT TO KNOW HOW TO TOAST MY BREAD!”
Don't get me wrong, API documentation has its place, but it is not a replacement for real documentation.
Good documentation answers two questions in plain English:
What: Imagine you're standing next to the user and describing all of the features of your project. The documentation is often the first place a user will go to see a list of features. Don't hold back your enthusiasm. Get them excited! Nobody likes dry documentation.
How: For every what, you need a how. If your library allows the computer to stand up on its USB ports and do a little soft shoe, describe exactly how the user can make that happen!
You may be saying at this point “that's what the tutorials are for!” Not quite. Tutorials describe how to accomplish a single, pre-defined goal. Documentation provides the definitive, detailed instructions for using every single feature, while providing the user with the knowledge necessary to tailor the instructions to their particular needs.
I've seen a number of projects that don't provide real documentation, but rather play “pass the buck” with good-hearted users who have braved the undocumented wilds and created tutorials. To be brutally honest, this is lazy, pathetic, and totally inexcusable. If you write the code, you have the obligation to provide the instructions to use it! Not writing documentation forces each user to spend two to three times the number of hours you “saved,” just to use the code you wrote.
That leaves the last question: “why?” I believe this should be answered by commenting your source code.
The main argument I hear for not writing comments is “Anyone can tell what the code does by reading it!” You're right, but that is missing the entire point of commenting. Sure, if I know anything at all about coding, I can tell you're using a loop that iterates through each element in an array. What I can't necessarily surmise is why you're doing that. In fact, I'd probably guess that you're using a linear search algorithm (which is quite possibly a bad idea), but since I can't read your mind, I'd likely never be inclined to tell you to switch out to binary search instead.
You will even forget your own reasoning after a while. Excepting those amazing individuals with flawless memory, any programmer who brags that he never loses track of his intentions after being away from the code for six months is lying to you, and quite probably to himself.
Good comments should describe why your code is written the way it is. You may comment that earlier loop with “We have to use linear search because the objects are unorderable.” For better or worse, your assumption is now clearly in the daylight. Four months later, someone else (or a future version of yourself) may come across that and think “Oh! We just need to overload a couple of operators, and those objects actually will be sortable!”
Commenting Showing Intent, as we call it at MousePaw Media, also enables new developers to get their bearings in the code very quickly. No matter where you drop into the source, you know almost immediately what the code is supposed to be doing. Barring comments, it is invariably daunting, and sometimes nigh near impossible to get started contributing to an open source project.
You may think you're saving time by not commenting your project's code, but you are actually confusing your future self, concealing bugs, and discouraging new contributors from joining the project. Not very time-saving after all.
If you want practical steps and examples for commenting your code effectively, check out MousePaw Media's official Commenting Showing Intent Standard.
I get it – maintaining a good README, writing documentation, and commenting code isn't glamorous, nor is it particularly enjoyable in the estimation of most programmers. After all, hundreds of open source software projects have survived for years, decades even, without these “extras,” right?
Maybe so, but I believe those projects have survived despite those problems purely on the basis of free-and-open-source-software ideology. Dedicated programmers were willing to tolerate, and even accept, lackadaisical documentation and sparse commenting for the glorious benefit of having functional free software!
Unfortunately for those projects, this is 2017. There is seemingly no end to the competition from other open source libraries and applications promising the same functionality, and many of the relative newcomers are much stronger in the areas of documentation and commenting. No project can rely on its feature-set alone for survival anymore.
A successful software project, I believe, answers those six basic questions we learned back in grade school: Who, What, Where, When, Why, and How. So let me ask you – if your old English teacher were standing over your desk right now, what would he or she have to say about your project?