User:QEDK/GSoC 2020/The why and how of writing good documentation


One of the best tips for publicizing packages is having a well-rounded and complete README, even at hackathons, it’s almost a pre-requisite. A suitable question is, why?

Case in point, I was looking to re-write a relatively simple Python package into Rust, and I found a certain crate which did exactly that — the downside, bare documentation. It’s quite often that even highly used libraries have inadequate, missing, or worse, incorrect documentation. Some package owners enforce documentation linting to ensure that every bit of the codebase has some documentation, that’s alright but it often leads to confusing one-liners with woefully lacking context but that’s just how writing code is.

Why and howEdit

I’m better at writing code than documentation, one point that became very clear while I was writing the docs for my configparser crate. For better or for worse, I challenged myself to write a contextual explanation, return types, and examples, for every function, struct, and implementation (and of course, a good README). One thing I didn’t know before writing docs in Rust is that examples are run (doctests) by default. At the time I started writing the crate, I had zero passing code snippets, now I have fifteen, with seven more to go. Doctests turned out to a very important requisite, especially with respect to the motto of never writing incorrect documentation. I often made mistakes while copying snippets which had minor errors, or incomplete signatures, which albeit easily fixable would inconvenience the end-user.

*insert witty xkcd comic*

Things are a bit different when you write a product instead, then a lot of the documentation revolves around “where things go awry” instead of focusing on doctests and the likes, since not all products are meant to be extensible, but even in that case, it becomes very necessary to write well-rounded and accurate documentation. Each time you make a product, there should a long-term view in mind, what happens when you’re away? Who steps in, and how? These are very important questions. Without good documentation, this is absolutely difficult, it’s important to make handing over projects as seamless as possible, and writing good documentation goes a long way towards that purpose.

But, writing documentation is hard work — it takes a while to dig into the code with your teeth and bring out areas where issues might come up or they already have. It’s even more necessary when particular functions might have overlapping, related functions or are simply too generic, for example, if a library has a function called load() and another called read() it’s not immediately apparent what each of them does, load what, read what. Ideally, when writing documentation you want to make everything clear as fast as possible, which means keeping things concise for the code-base and having verbose documentation for when things go wrong or are simply unclear. This applies to products and even more strongly, libraries. (I’m just fed up with documentation-less packages!) Remember that most end-users will probably move on to using software that tells them where they are going wrong, and it’s best to not be opaque about things, I’ve seen many instances of errors which are simply too widely-applicable or plain generic to help users to correct their mistakes. If my return type is expected to be an int, I want to know where the int is coming from (if it’s not immediately apparent).

However, writing documentation does not always have to be difficult — if you’re doing API documentation in Python, you should use something like PyDoc, Doxygen, or for a different flavour, Sphinx. In Rust, let rustdoc do everything for you. For documenting products, a good README is the best entry-point, branching off into links to other documentation files or a compiled wiki dedicated to documentation. Then, it’s not as much how something is done but what is being done.

Drop by in the comments if you have anything to add. Next time, more about what’s next (and I’m excited). 😊

  • Deploy to Toolforge and monitor in production
  • Fix Kubernetes builds
  • Deploy hotfixes and add error-control
  • Welcome users via PM
  • Make welcome message more descriptive
  • Release the MVP