Perl6::Math::Matrix (Part 5: patient with docs)
If you write any software package, you have to document it. This simple truth drives more than few developers into despair. But there is also a way to craft good documentation and make the writing of it a useful part of the development. This is the closing part about authoring a Perl 6 module and Math::Matrix in particular (part: one, two, three, and four).
Since Perl 5.0 we have a markup language called Plain Old Documentation, that can be embedded into code. And becasue Perl 6 is a complete overhaul - the power of POD was also extended. One of the most interesting expansion is the metamodel-method HOW that can recall the documentation associated (written in front of) with a routine (sub or method). However, I did not use this feature yet, because this topic contains math that requires much longer explanations and examples, than I would want to see as a quick help output in the shell. I plan to supply this kind of docs later, as a summary of the well rounded documentation we will have then.
Also a product of our relative early stage in development, is the decision to put all documentation in one .pod file. Its just easier to add or rewrite sections, regroup content and maintaining the links, when all is in one place. And to co-maintain the documentation with the sources, while the final layout is not found is just one more brick I don't want to shoulder constantly. Nonetheless, the ordering of the docs will give you an orientation where to find what in the sources (section - and method - wise). I think that is a useful service to interested people that might want to contribute. It also helps you (the author) to detect if the code structure is not well thought out or even if your API has issues. Last but not least converting documentation into other formats is a bit easier when handling just a single file.
Da Don's Way
Donald Knuth is not only exceptionally good at writing software, understanding algorithms and writing books about both topics. It is also worth to hear his advice about how to document software. One big point is: don't be sparse - but leave the same information at least in two places, so people get their answers on the spot they look for it and don't have to navigate your chapter structure too much. This notion of: documenting always a little more than, lets say a math textbook would do, has also the good side effect, that your docs become more beginner friendly.
Going To Chapter
But surely there is a limit: staying on topic of the chapter. And a chapter should be rather short. So if it gets too long - rather break it up. This way you can later link exactly the content you want and not 2 paragraphs in front of it. Unlike HTML, in POD only headings can serve as link anchors.
And its also worth the effort to make the headings itself into a link that jumps one up in the hierarchy (works much better with smaller chapters). This and an extensive and well structured table of content ( TOC ) makes it much easier to jump to the information you looking for.
Having smaller, precisely named chapter has even another benefit. They provide context to the paragraph below and can help to shorten sentences without any loss of information.
Some people will use your chapter hierarchy, but others will obviously just use the search box. To provide for them you have to anticipate the keywords that belong to a chapter. This includes in our case mentioning alternative names of mathematical functions. In part 4 I wrote down the rationale, why I named a method adjugated. But in its documentation I start with calling it also classical adjoint and adjunct, so folks, that are used to the other names, can still find the function.
Paste and Cut
Uncle Bob advises us to treat our code like a boy scout: always leave it a bit cleaner after you visited it. Same can be said about the docs. But in contrast to code - where only the result matters to the user - documentation can be polished nearly indefinitely to the benefit to the reader. To be real, try at least my three pass rule. 1. Just document what you want to implement. 2. Think about what could be added to be more useful, to lower learning curve, to teach the idea behind a method or naming schema, providing an example and so on and on .. 3. Cut the fat. Reformulate to get less text with shorter sentences. Trim all sentences and remove bloating words that do not add necessary information. Check if what you explain is in the scope of method or you should link to a chapter where it fits better. Look if there is a shorter example that demo's a normal use case but also clarifies some corner case (so you don't have to explain it with many words).
Last time I presented the the concept of domain driven design. It shares it's initials with the much lesser known Documentation Driven Development, which is basically the idea: document first and implement later. In my mind this has several advantages. During the planing phase it is just helpful writing down your ideas, so you can better reflect on them. Doing that with the attitude of explaining it to someone else just adds to the process. In return you get a skeleton documentation that also will give your code base a mental structure.
Before you implement a method you should also document it. Your understanding about what to write will be much clearer and coding will be more straight forward. (And you ensure that the docs are always complete and in sync with code.)
Some people recommend writing tests first for the same purpose, but I disagree. First off, test are still code and writing docs bringing you out of the programmers mindset, helping you reflect from a more eagle eyed perspective if the method makes sense, if its API is well set and if it fits in the overall design of the module. Once these questions are cleared, you can ponder the implementation details - which is really what tests do check. Software tests are much better utilized as a moment of after thought (pondering if your implementation be optimized or some signature detail can be streamlined).
This design flow from the general to the minute, in my experience, also reduces the need of a rewrite. With TDD you might catch a design flaw too, but you still have to then re-implement the method and rewrite the tests (again). When you can catch the same issue while writing the docs it saves you work. Once you understand this cycle, you're more motivated to write (better) documentation. And in the end is seriously thinking about how a hardened API should look like and writing it down way more entertaining than refactoring.
If you want to know more about how I see the interplay of planning, implementing, documenting and testing, look out for my forth coming article on Complete Programming - that's how I named my take on software engineering.