I am currently developing and maintaining a PHP framework, and when writing documentation I find it hard to see the difference between useful docs and non-useful remarks. How do I get better at writing documentation?
You are not only writing documentation. You are also writing sales copy for your framework. Recognize that developers will come to your API docs with two possible mindsets:
1) Evaluation stage: Developer arrives at API docs with goal of determining whether framework solves problem within unique set of constraints. Expect him to skim docs, searching for keywords related to constraints, and/or any examples similar to problem.
2) Implementation stage: Developer has settled on your framework (at least initially), and is ready to build first project. Will either complete project, or abandon framework, depending on technical quality of your docs.
These two mindsets represent two components of a sales funnel. On the docs landing page, your primary goal should be converting developers from Mindset #1 --> Mindset #2. If you look at popular docsets, you'll notice that the intro pages tend to read like sales pages. Why should you use this framework? What are some popular production implementations? Any cool examples?
Deeper in the docs, you simply need solid technical documentation. Other comments here have great tips. Just keep in mind that Mindset #1 will barely skim these areas of your docs, but will definitely consider them briefly.
Disagree with the first point. Sales obscures facts in order to convince someone to use your thing at their expense. Docs should put facts out more plainly and turn away developers from your framework as quickly as possible. If it's not what they want, say so.
Here is an example of 'sales copy docs':
Minuteman Framework
!!! Gets your missiles launched in seconds!
!!! Produce reports of completed strikes!
!!! Makes a great pasta salad!
Versus an example of 'real docs' provides and requirements:
Minuteman Framework
!!! Provides a C library and python, perl and ruby bindings for assembling, scheduling, executing, and reporting on minuteman launch capabilities for a variety of platforms.
!!! Supports only ARM and SPARC architectures.
!!! Requires 3 active nodes on 5 different networks for high availability.
!!! No REST API support.
I see your point. However, sales does not necessarily imply meaningless marketing copy. You act as a salesmen every day, any time you try to convince anyone of anything. A good salesman is not dishonest. He's honest, understands his customer, and guides the customer to a (mutually beneficial) solution to a problem.
Sales is not dishonesty, despite the stubborn misconception commonly held by engineers. In reality, sales is the process of convincing someone that Option X is in his best interest. There should be no trickery involved. If you're a good salesman, you can convince without dishonesty.
>Sales obscures facts in order to convince someone to use your thing at their expense.
There are honest sales techniques, too. Dishonesty is a great way to burn your long-term social capital for short-term gains. Like, how I'd phrase that is your docs should either sell developers something they end up wanting, or help build a long term relationship by pointing out that it's not something they want.
One thing I would add onto the notion of documentation acting as a sales tool... even once you've managed to convince a developer to use your tool, he or she may need to convince their management of the same thing, so good documentation can provide them with the "sales" points they need to get your framework adopted by their company / team / project lead. Good documentation not only informs and excites the end user of the tool, but should also provide a basis of value for any other stakeholders in the outcome of its usage.
Accomplishing these "salesy" tactics while not appearing needy or shoving bullshit down someone's throat is a very fine line. The world needs more technically informed writers, and more developers should work on their writing abilities. It's a definite art / science combination that makes most technologies successful.
This is personal, but I taught myself how to code, before the internet, and with barely any books. One thing that made, for example, the PHP documentation a lot easier to read vs. Perl was: examples
On an API level, don't just explain what things do, but how to use it, what is the intention behind a particular call or method, and how it integrates with other pieces of the environment. If there are best practices, this is the place to call them out. And it does not need to be a tutorial, but if the class calls for a "usage sample", that is perfect for the documentation.
Pick on these:
1) What decisions did you take for the implementation?
2) What tradeovers are made (this is written like this because ...)
3) How is it supposed to be used
4) What is the common pattern for accessing the resource (instantiate it, factory, singleton, dependency injection?)
5) How does it relate with the rest of the codebase?
Now, this is PHP, but on other languages...
6) Is it Thread-Safe?
7) How cheap is it to instantiate a new object of that type?
These are some very good points! I already try to explain in my documentation why I wrote the code like I did, but I guess I'm afraid I'll bore the reader to death with it. Describing common patterns, or good practices is also something I try to do regularly.
The relation to the rest of the codebase is something I don't really get: do you mean I should explain why this piece of code is consistent with other code? Or the documented code interacts with other pieces of code?
I would imagine the relation to the rest of the codebase is how/why it interacts with the rest of the code. This is often valuable to know as its rare you are using just a single piece of a codebase in isolation, and relations among pieces are very helpful for developing intuition about them and the codebase as a whole.
First you should decide who the intended audience of your documentation is. Who are you trying to help, and what are you trying to help them do?
Then, partition your mind into two halves. The first half contains everything you know about the project, and the second half contains everything your imaginary new reader knows, which may be nothing.
Identify each difference between these two bodies of knowledge and, starting with the largest and simplest, write down what the reader needs to know in order to transition from one state of mind to the other, in as succinctly a way as possible.
If you start rambling, go back and edit.
I find this works for explaining many things, not just software projects.
Read other documentation. Discover what choices the writers made (implictly) and what works for you w.r.t. structure, clarity, completeness, conciseness. In your case, look for documentation of other (web) frameworks with a large audience, for example:
I'm glad you are concerned about documentation. Poor quality docs are the bane of many opensource projects. The most important thing you can do is draft your initial docs and then have someone with the minimal level of expertise or experience try to install/implement your code using only the docs. The stumbling blocks that the user reports will tell you where your docs are lacking. Ideally, after you make the first adjustments to the docs, you should find someone else to test them on. Repeat this process with new people until you have good docs.
Also, include a good project summary. You'd be surprised how many projects don't include that. They just assume that everyone knows who they are and what their code does.
I enjoyed both "The TeXbook" and "The METAFONTbook" as great documentation. It helps that they're literately programmed, obviously, but you can't go wrong reading Knuth's commentary.
You stop writing code for a 'week'. Don't 'touch' the codebase during that time. Come back after that duration has passed, re-discover the code and write the documentation then.
I understand, there's a threshold beyond which the details of your code become somewhat blurry. I shouldn't have emphasized the duration as I'm not entirely sure what it amounts to, usually a week is enough for me :) The point is, find something that will distract you enough to forget these details, allowing you to become your target audience while writing the documentation. This is one way to zoom out and discover what is important and what is not.
Steal someone else's doc. Someone who did a good job. (CC-SA licensed or similar so its legal) (And edited to add, doing the right/moral thing wrt attribution and thanks, is important, not just doing the absolute minimum that whatever legal license requires)
Not kidding. Its an effective checklist and provides decent balance, at least a first guess at checklists and balance. Think of it like a development framework... for docs.
A really difficult startup problem (aka a good one) would be automation for doc writing. When you code its really easy to have automated syntax checkers and testing systems and A/B binary search algos to scan thru a git repo to find when a bug was introduced... and when writing docs its still the 1980s, maybe 1990s, you've got a spell checker and maybe a grammar checker and possibly some kind of "grade level analyzer" that just looks up and calculates average syllable length of words. There must be something better out there.
There have been no shortage of historical attempts at inline doc generators and template systems and markup language for technical docs. However, none have revolutionized the world, at least not yet.
(Edited to add, just caring about this issue puts you ahead of the pack, which is either a very optimistic comment WRT you, or very pessimistic comment WRT everything else on average... Glass half full or half empty LOL)
In Chapter 15 - 'The Other Face' - in the "The Mythical Man-Month" by Fred Brooks, there is a section on "Self-Documenting Programs." There is a code example that has more documentation and comments than code - it looks exceptionally thorough. In addition, Brooks lists an approach and some techniques for documenting a program.
One may even consider tests as part of documentation because they are functional representations of the logic you've developed - they can be the examples that can show how to and how not to use the program.
Here is a link to the mentioned chapter and figure (15.3 A self-documenting program) from "The Mythical Man-Month":
Technical documentation is hard, really hard. It's easier to explain what not to do.
Some suggestions:
- It's no prose, so don't try to be arty.
- Keep it short!
- When in doubt, drop it.
- Use simple words. Not everyone is fluent in English.
- Any sentence with more then two lines is an anomaly.
- Be consistent. Avoid surprises.
- Usecases and Examples are important and may shorten explanations.
- Include common mistakes and their workarounds.
- You have to refactor often (>>20x).
- Use a versioning system like git or mercurial.
- Avoid abbreviations and introduce them at first occurence e.g:
concurrent versioning system (CVS)
- A colum shouldn't exceed 9-12 words (~60 chars) to improve readability.
- Keep your rules in a file (e.g: doc.playbook) and check them
- Let others proof read, or yet better find an editor.
- Try to be gender agnostic. Why? cautionary tale:
https://github.com/joyent/libuv/pull/1015
1st documentation inside the code should be used sparse. The code should be obvious, and PHP code could be readable, if you use good names, and proper indention. Comments should only point to traps and tricks.
2nd documentation for those who use your code. This should come in two flavors. You need manual pages for command line and styled HTML for browser. PHP offers XSLT making this task very easy. See http://kephra.de/src/php-xslt-doc/ as example. I'm sure that there are many more fancy PHP documentation packages around. But mine counts only 533 bytes.
3rd and last we have the documentation that describe the design of the project. I often use a MediaWiki + xfig for this, generating additional graphics with GNU plot or batik for SVG. But your mileage may vary here. PHP does not offer a straight solution to this wide problem, afaik.
The most important thing is to make the API design not only easy to use, but also slightly defensive. If people should doing things one way, guide them toward that in the API, and make it harder for them to do the wrong thing. A lot of documentation can be made redundant in this manner.
As for the documentation itself, I know of no good way to put yourself in the shoes of someone who does not know your API - you are just too familiar with it to be a good judge of the documentation. Instead, test it. Get others to read it and try to accomplish particular tasks, invite feedback (and be open to it - if they get something wrong it's not their fault, it's yours, they're the experts in how useful this documentation is so listen to them), and iterate.
This is one of my favorite topics! The basic process I follow is:
1. Imagine you are a use who knows nothing about your framework. What would you need to know next?
2. Write that.
Step one is really really hard. It takes a powerful imagination to pretend that you don't know something and hop the fence from framework producer to framework consumer. There's no easy way to do this aside from practice and talking to users lots.
In terms of just generally writing better, here's some basics:
1. Revise. Revise. Revise. That writer you love's first draft is just as shitty is yours. The difference is you never see their first draft, you see their eighteenth.
2. Reading out loud helps a lot. Yes, even for technical docs. Yes, it feels weird. Do it anyway.
3. Brevity matters: you want to distill your knowledge to its essence. But note that it's a distillation process. In your first draft, just dump it all out. Worry about condensing when you revise.
4. The written word, especially technical writing, by default, comes across as emotionally cold and unfriendly. Words don't have facial expressions and tone of voice. While technical writing isn't read purely for pleasure, you'll get a lot of value out of trying to make it a little more engaging and pleasant to read. Don't be afraid of a little emotional language. You'd be surprised how much of a different starting a paragraph with "I'm really excited about this feature..." makes.
5. Give someone a couple of examples and they'll delight in finding the generalization on their own. Going the other direction is a lot less fun.
6. Different readers have different learning styles. You may have to say the same thing in a few different ways or a few different orders to reach them all. Balancing this with #3 is an art form.
The fact that you're asking at all is a great sign. (See! More positive language!) If you care about your docs as much as you do about your code, that is, by far, the most important ingredient to being a good writer.
Start by having a one-line description saying what every file, class, method, function, etc., is for. Where needed, expand on what parameters are expected, and give examples of usage. This is the API reference and it can be automatically extracted from the source code if it is part of comments.
For a getting started / user guide, give a higher level description of how components tie together and show end-to-end usage examples. The key here is to be succinct but include all the information that a new user will need to get started. Whenever someone asks a question, this is a good sign that information should be added to the docs.
Don't focus on the Perl language, just on their best practices for documentation. the guideline in terms of content are totally relevant for any language/developers and polished by practice.
Even if I chose to switch from Perl to python, I still miss Perl in terms of module distribution/testing/documentation.
Perl, and Perl community, I miss you, and I value what you learnt me :)
I advocate for people to be open minded and take good ideas without prejudice on their origins.
You have just found a hard problem. :) More seriously I find depending on the users needs, different documentation are needed. Documentation for beginners. Specifications which include any gotcha that anyone ever tells you, also what it doesnt do that people try. And how-tos to get stuff done. And never believe anyone who tells you the code/test documents itself. It doesn't. It just means your trying to get the users to document it for you. Which isn't terrible if you have to do it to lower cost, but lowers uptake, and gives a worse experience.
Simpler & more succinct code is also easier to document. So if you have functions that are several LOC long, simplifying / dividing them into smaller functions can be helpful.
Everyone here is saying to give lots of examples: I would add to not ONLY give examples, but also make sure you explain parameters, return types, etc.
The most frustrating type of documentation for me is when there are usage examples but nothing else. Then, when I invariably want to use the library in a way that's slightly different than the provided example, there's no documentation available.
Especially in teams, one thing I've found that helps in documentation is standards and templates. If everyone knows exactly what to document, how to document it, and where the documentation lives then it's much more likely to get done and done well.
Start with a minimal set of standards and templates and build up, rather than over-engineering and not getting anything done.
You should create a bunch of tutorials and provide index-like descriptions of functions in the form like this:
1. Syntax
2. Params
3. Examples of use (the more the better).
This way you will spend less time and get more satisfied customers.
Imagine you are sitting next to a person who will be taking over your code. How would you explain your code to him/her? Just write down that imaginary conversation and very likely you will have the best documentation of your code.
Start off by reading documentation, preferably good. It's not easy, but just as everything else you will get better with practice so you'll have to just write. You can always go back and revise just like your code!
Actually use the framework (every feature) and write down everything you needed to know to use it. Really, the more time you put into something the better it will be, so just make a good effort and it will be good.
I do use the framework quite a lot. Actually, I'm not even sure there are loads of users or something like that. It's more like a personal project that has the potential to be used in many projects.
But yeah, I'm a pretty heavy user of my own framework :)
I cannot stress this enough: write good code! Any decent code editor now jumps you to the source of the code you're calling allowing you to quickly see what the code does, what parameters are needed, etc.
In fact the best documentation I've seen (say flask, django) most of the documentation acts as support for reading the code.
1) Evaluation stage: Developer arrives at API docs with goal of determining whether framework solves problem within unique set of constraints. Expect him to skim docs, searching for keywords related to constraints, and/or any examples similar to problem.
2) Implementation stage: Developer has settled on your framework (at least initially), and is ready to build first project. Will either complete project, or abandon framework, depending on technical quality of your docs.
These two mindsets represent two components of a sales funnel. On the docs landing page, your primary goal should be converting developers from Mindset #1 --> Mindset #2. If you look at popular docsets, you'll notice that the intro pages tend to read like sales pages. Why should you use this framework? What are some popular production implementations? Any cool examples?
Deeper in the docs, you simply need solid technical documentation. Other comments here have great tips. Just keep in mind that Mindset #1 will barely skim these areas of your docs, but will definitely consider them briefly.
So, in brief:
1) Sell developers.
2) Write good technical docs.