As I said in my last post, many of the language communities that I interact with now are fond of asserting that their particular community does a wonderful job of testing, documentation, or both. This time, I’d like to examine the claims on documentation.
Once upon a time, all of the documentation for a language either came with the CDs (or other media) when you bought the compiler, or were available for purchase as books. O’Reilly Media started as a small publisher that supplied books on open source tools and languages.
Many modern languages tout their extensive documentation. They talk a lot about their culture of documentation. Most of my recent documentation experience relates to Perl 5, Ruby, and Rust. My experience of Java documentation is many years in the past.
While most libraries in modern languages come with documentation, the quality of that documentation varies. Of the three listed above, I have to say that the documentation for Perl modules in general is much better than Ruby gems or Rust crates.
The Easy Way
Back in the late 90s and early 2000s, Java (and to some extent C and C++) adopted an approach to documentation based on annotating the source code with comments around classes and methods. This Javadoc style did move developers from no documentation to some documentation, but it did not provide more than the bare minimum. Unfortunately, people who learned that style brought it to other languages.
A Documentation Convention
The original Perl 5 module documentation was strongly influenced by Unix man pages. Over time, a convention developed around a series of sections for module documentation. Since all modules follow a similar format, it’s really easy to find what you need. The standard sections are:
- NAME
- SYNOPSIS
- DESCRIPTION
- BUGS/CAVEATS, etc.
- AUTHOR
- SEE ALSO
- COPYRIGHT and LICENSE
Most of these sections are self-explanatory. The DESCRIPTION section usually contains almost everything found in most of the library documentation in other languages. It normally contains classes, functions/methods, and constants, organized in subsections.
A Critical Section
The section that I miss the in most other languages libraries is the SYNOPSIS. It provides an example usage of the module, which may be as short or long as the author thinks is useful for people to get a feel for how to use the module. This code is usually safe to copy into your project to use to get started.
For some gems or crates, I can find the equivalent by searching on the web, but that is often not ideal. Will the examples I find refer to this version of the library or an older one? How do I know that the person who wrote the example knew what he/she was talking about? How likely is it that the example shows how the author intended for the library to be used?
Having a synopsis or example in the module gives me some reason to believe positive answers for all of those questions. The synopsis is not guaranteed to be correct. Sometimes they fall out of sync with the code. Sometimes the author didn’t pick a good example. But, those kinds of documentation errors often result in a bug report or pull request in the Perl community.
But Wait, There’s More
In many of the larger or more powerful Perl module distributions, the authors commonly add more extensive documentation, including:
- Getting Started/Quick Start Guide
- Tutorial
- Cookbook
If configuring the module or getting set up for your environment is complicated some form of Getting Started guide helps people get over the first hump. If a new user cannot get the module up and running, they aren’t going to use it.
If the module assumes a certain mental model or approach to solving problems, a tutorial is quite helpful. The goal here is to walk the user through some of the more common use cases and give them enough information to continue on their own.
If the module supports a large number of use cases or has a number of smaller pieces, a cookbook formatted document can help. This will focus on explaining how to solve certain tasks for the user using the module.
Unlike most libraries I’ve seen in other languages, this sort of information is supplied by the module author, directly as part of the module distribution. Very large frameworks in other languages may provide something similar (Rails for example), but it is does not appear to be a standard approach for libraries.
Improvement By Nudging
There are a number of testing modules in the Perl 5 ecosystem that focus on improving documentation. Mostly, they just make sure you have the appropriate sections in your main docs and that every public method/function has documentation. Despite their simplicity, they serve as a gentle reminder to add some minimal documentation.
Of course, there’s no way for a testing module to make certain you’ve written good documentation, and someone can certainly skip those test modules and the documentation they suggest. However, the slight nudge of the tests and the comparison with the other modules on CPAN serves as gentle peer pressure to help people improve their modules by keeping their documentation updated.
Some Good Examples
As a quick experiment, I decided to take a quick look at libraries from languages I don’t use as much: Python and JavaScript.
A quick look around the Python Package Index showed very inconsistent documentation, ranging from none at all, to really good. Quite a few Python libraries included an Example section, that served the same purpose as the Synopsis that I was wishing for above. There did not seem to be as much consistency of format between documentation, but the libraries that I saw that had documentation, seemed to do well.
For JavaScript, I looked at libraries on the NPM site. Once again, I saw varying quantity and quality of documentation. In the better documentation, there were examples in either a Usage or an Examples section.
Standing on the Shoulders
Like I said in the previous post, there is nothing preventing library authors in other languages from providing the level of documentation that is common for Perl 5 modules. In fact, this is easier than the testing infrastructure I described last time. All it takes to improve the documentation for your Ruby gem, Rust crate, or Java library, is to realize that your users need this information and write it. Writing good documentation isn’t easy, but the effort really helps your users.
The Python and JavaScript communities are definitely doing a much better job in this regard. They might also learn from Perl 5’s lessons on adding documentation analysis and reporting on their libraries. The communities should also focus on some gentle peer pressure to get library authors to do a better job on their documentation.
I know many people out there have the view that everything associated with Perl 5 is bad. But, the Perl community has done a great job with documentation. One of the biggest drivers for this was the community realizing years ago that not all module documentation was great and deciding to start encouraging module authors to improve. Other language communities would do well to learn from this experience.