Friday, October 25, 2013

My #1 Tip for Technical Writers

There are so many docs out there that don't seem to get this. If I could offer one tip for anyone who writes technical or scientific documentation about anything, it's this: use examples. Lots of examples, the more the better. Not just examples--put explanatory prose beside, above or below your examples, but use examples liberally. Diagrams and pictures don't hurt either.

It's fundamentally hard to put abstract technical concepts into words, and I've noticed that most people aren't that good at it. Human language is quite ambiguous and besides, we often make mistakes in our writing that can make our prose confusing. I think I'm better than average, but often when I re-read something I wrote a long time ago, I realize that it's ambiguous or that it hasn't given all the information necessary for a novice to understand it, and I have to clarify. (TODO: give an example here.)

The only trouble with giving examples is that it can be hard to find good ones. For example, I'd like to give examples from my own life of the things I'm talking about in this post, but it's hard for me to remember my own life, so nothing is coming to mind.

Examples can often provide the clarity that the text is lacking, because
  1. they restate the information in a completely different form, giving the reader a different perspective on the topic.
  2. they make abstract ideas concrete, or visualizable in the mind's eye. Such concrete things are easier to understand and reason about than abstract generalizations.
  3. they can constrain the possible interpretations of the main text: they can resolve ambiguity by showing that certain interpretations are impossible.
A poor example is one that doesn't have the above advantages:
  1. If the example is too general and somehow matches the abstract description of a concept, it isn't very helpful. For example, if you're trying to explain what a list comprehension is, S = { f(x) | x ϵ T } is a terrible example; it demonstrates the syntax, but nothing else. A better example would be something like Doubled = { 2n | n ϵ Original }. Once you explain that {...} represents a set of things (in this case, numbers), that "ϵ" means "is a member of", and "|" means "where", the reader can start to understand the explanation: this takes all the numbers from a set called "Original", doubles them, and uses "Doubled" as the name for the result.
  2. If the example isn't something concrete, it may not be very good. For example if you want to explain how to use an API called, let's say, Scan(), and your example is simply Scan(foo, bar), it's worthless since "foo" and "bar" are not concrete things that people can imagine. That's not to say one should never use "foo" and "bar", but if your example will make more sense if it is based on a real-world scenario, then base your example on a real-world scenario.
  3. They can constrain the possible interpretations of the main text: they can resolve ambiguity by showing that certain interpretations are impossible. For example, suppose a small child just learned to add numbers, and now you want to teach the child about multiplication. Then "2 × 2 = 4" is a terrible example to introduce multiplication: the child already knows "2 + 2 = 4", and it looks like you just rotated the "+" sign. The example sucks because it fails to show how multiplication is different from related concepts. Likewise "3 × 1 = 3" is a bad example: it does not illustrate the purpose of multiplication (and obviously you shouldn't start with "3 × -4 = -12", it's too advanced). Eventually you can show these examples if you want, but first you must show what multiplication is, how it is used and why it is useful.
One more thing, when giving code examples, make sure they compile, and preferably, mention the environmental conditions required to compile them (#include files, assembly references, compiler options, etc.)

Tuesday, October 8, 2013

LLLPG: almost done

Yesterday I published a new article about the Loyc LL(k) Parser Generator.

Formalism tutorial

Have you ever seen notation like this in a programming language paper?
I have. And it's completely frustrating to encounter notation like this, because there is no obvious way to find out what it means. The paper itself will not give a name to the notation they are using, and there is no way to Google for the symbols that are used. Even if you can find one of these symbols in Character Map or whatever--and it probably won't be listed under standard fonts--Google responds with something like
Your search - ∏ - did not match any documents.
Luckily, I stumbled upon this page which briefly explains, and gives names for, these notations. For example: "|-" means "entails", "<:" is a subtype relation, ⊥ is "bottom", its inverse Τ is "top", Γ is "context", and the long horizontal line is sort of an if-then statement:
"if everything above the bar (the premises) is true, then the thing below the bar (the conclusion) is true"
Excellent, this will be very helpful when I encounter another one of these papers. I wish computer scientists understood that their notation is far from universally known and that, without a "legend" or informative URL, mere computer engineers like me not only cannot understand the notation, but cannot learn about it either.

Update: here's a more detailed introduction to Programming Language Theory.