Some of my readers have, over the last couple of days, commented on the script documentation from the perspective of our discussion of syntax and semantics:
The language in which the scripting documentation is written consistently gets in my way when I'm looking for information on the semantics of a scriptable API, by repeatedly addressing the syntax, probably in the assumption that scripting languages are for beginners and beginners tend to forget about the syntax.
Look at the CLR or PSDK docs, which essentially target non-scripting programmers; while they have their own share of problems, they have at least the advantage of actually being reference texts, in that they precisely and concisely define a specification for an API. The scripting runtime docs just leave too much to the imagination.
I think that it is fair to say that no one who worked on the scripting documentation is entirely thrilled with it, and yes, there is certainly room for improvement. But I'd like to take this opportunity to state clearly that this is not evidence that the documentation team consisted of a bunch of bozos. Far from it! The User Education people I've worked with over the years have a deep understanding of the technologies they work on, and excellent communication skills. People who can rapidly come up to speed on a brand new technology, understand the usage scenarios, write sample code that uses that technology and have excellent command of both English and the specific requirements of technical documentation are rare. They are in considerable demand at Microsoft, and there are often too few to go around.
Every time a new feature is proposed, representatives from all the disciplines sit down so that we can figure out if there are enough warm bodies to change a lightbulb. Are there enough developers with free time to write and test the feature? Are there enough testers to verify that the developer did a good job? Are there enough program managers to write the specs and herd the cats? Are there enough writers to produce the documentation? If the answer to any of these is "no", then either the feature gets cut, or we negotiate. If UE is the bottleneck then we might make the feature less complex, cut a less important feature, borrow a writer from another team, get the devs and testers to help write and test the sample code, scale back the depth of the documentation, and so on.
When making feature decisions the script team was often constrained by our overworked UE team. Something had to give, and we ended up doing all of those things I mentioned at one time or another. We made sure, however, that extra effort would be made for particularly tricky topics -- the file system object and regular expressions come to mind. I wrote a lot of FSO sample code and spent a lot of time scrubbing the regular expression docs.
The docs are far from perfect, but I hope they are at least somewhat useful. I also hope that by blogging, I can provide some of the extra conceptual context missing from the documentation. If people have specific ideas for future topics, please let me know.
Mike (who is one of those rare people who can write code and learn new technologies in great depth extremely rapidly and then write sensible documentation) pointed out
different types of documentation are written in different ways. The example you cite is from a reference topic. That type of documentation is traditionally written tersely because reference docs are to some extent written for the already-experienced programmer who does not need a bunch of background information repeated when all they wanted was the syntax of method such-and-this. You'll note that almost all reference material for all languages -- JScript, C#, Java, T-SQL -- follows this philosophy.
Good point. I want to talk a bit about the design and documentation of APIs from the perspective of the various constituencies I mentioned yesterday. Recall that there are three large buckets of developer customers that we think about a lot here:
- the LOBDev -- the line of business productivity application developer
- the ProDev -- the professional application developer
- the Architect -- the design-the-whole-system developer
One aspect in API design that we think about when designing APIs for these various constituencies is how "global" does your understanding have to be to use the feature?
That's a bit vague, so let me give a few examples.
- To use the WSHNetwork.UserName method you need to understand how to create an object and call a method on it. That's two lines of code, which can appear pretty much anywhere in your program.
- To create a type-safe dictionary object in .NET you need to understand classes, inheritance, protected vs. private data, the relationship between enumerator objects and collection objects, etc. The scope of understanding is larger -- you need to have a pretty thorough understanding of how the base class works, what those half-dozen collection interfaces do, and lots of OOP concepts.
- To create an MFC MDI application, you need to understand the model-view-controller design pattern, how documents and views are implemented in the MFC framework, and all the details of how to implement each in an object-oriented fashion. If you don't understand that pattern, you simply can't write sensible MFC MDI code -- even with a wizard generating most of the boilerplate for you.
See what I'm getting at? The LOBDev likes to design methods which call other methods. The ProDev likes to make classes which extend and use other classes. The Architect likes to make whole systems where various parts interact in complex conceptual ways, but based upon system-wide design patterns.
The needs of the developer we are targeting have a huge impact on both the API design and the documentation.
- Documentation for Architect features starts with broad conceptual overviews and philosophical justifications for the whole design, and then delves into specific arcane details of how to make the interactions work. (Architects like nothing better than going on summer vacation with a big stack of Design Pattern books and a few thousand pages of framework documentation.)
- Documentation for ProDev features starts with an overview of the class and describes what the superclasses, subclasses and related classes look like. Most of the .NET Framework documentation was designed for ProDevs.
- Documentation for LOBDev features concentrates on the syntax and the most common usage cases, and little snippets of code that can be cut and pasted. The script object model documentation was written with this constituency in mind.
Now, obviously the Architects and ProDevs are going to need to know the syntax of individual methods at some point too. But my point is that if you are designing a feature for use by LOBDevs, you cannot require them to read ten pages of conceptual documentation describing the model-view-controller design pattern! LOBDevs have a big pile of widgets to frobnicate! By Wednesday! LOBDevs want a chunk of sample code that they can copy, tweak, and get on with life, not an essay on framework design.
LOBDevs want documentation where one page explains everything they need to know about making one method work -- which is why the script object model documentation seems so repetitive, and why there are so many seemingly-pointless little code snippets. The usage case goes something like this. "I'm writing a script to run the widget invoices through the gnustotron. Dump them to a temp file, run the gnustotron, hmm, I probably should delete that temp file. Let's google 'msdn script delete file', I feel lucky… and I am lucky! I'll just cut and paste that, change the file name, done." And then next time the LOBDev needs a method on a file, just type MyFile. and hopefully Intellisense will help, no need to look at the documentation at all.
This is also why the script object models are, by and large, collections of methods that do stuff. Fetch this user name, delete that file, etc. That's not very OO, is it? In a traditional OO design, objects encapsulate state, methods manipulate state. To understand what an enumerator does, you need to understand how collections work, how changes in collection state affect enumerator state, blah, blah, blah, lots of doc to read -- the ProDev has time for that. Heck, the ProDev is paid for that. For the LOBDev, life is too short to spend it reading about the OO design patterns that motivate collection semantics.
There's no doubt that we can make the documentation and the tools better, but better for whom? is an important and extremely difficult question. I'll try to discuss these tradeoffs in more detail in future blog entries.