#lang scribble/doc @(require "common.ss") @title{Documentation as Code} Most existing documentation tools fall into one of three categories: @|latex|-like tools that know nothing about source code, JavaDoc-like tools that extract documentation from annotations in source code, and WEB-like literate-programming tools where source code is organized around a prose presentation. The @|latex| category includes general word-processing tools like Microsoft Word, but @|latex| offers the crucial advantage of programmability, where macros enable automatic formatting of API details. Systems like Skribe@~cite["Skribe"] improve @|latex| by offering a sane programming language. Even in a programmable documentation language, however, a lack of connection to source code means that information is duplicated in documentation and source, and binding and evaluation rules inherent to the source language are not automatically reflected in documentation and in examples related to those bindings. The JavaDoc category includes perldoc for Perl, RDoc for Ruby, Haddock@~cite["Haddock"] for Haskell, OCamlDoc@~cite["OCAML"], and Doxygen@~cite["Doxygen"] for various languages (including Java, C++, C#, and Fortran). Such tools improve on the @|latex| category, in that they provide a closer connection to the programs that they document. In particular, they are specifically designed for library API documentation, where they shine in automatic extraction of API details from the source code. In contrast, these tools are not suitable for other kinds of stand-alone documents, such as overview documents, tutorials, and papers (like this one), where prose and document structuring are more central than API details. Literate programming tools like WEB@~cite["litprog"] and @tt{noweb}@~cite["noweb"] are designed for documenting the implementation of a library as much as the API that a library exports. In a sense, these tools are an extreme version of the JavaDoc category, where the information communicated to a reader is drawn from both the prose and the executable source. In doing so, unfortunately, the tools typically revert to a textual slice-and-dice of the program and prose sources, instead of a programmable layer that spans the two halves. @emph{Scribble} is our new tool for writing documentation in PLT Scheme. To a first approximation, it belongs to the @|latex| group of tools, but like the other two categories, Scribble creates a connection between documentation and the program that is describes---without restricting the form of the documentation like JavaDoc-style tools, and with a more nuanced connection to the language's scoping mechanisms than WEB-like tools. Specifically, Scribble uses ordinary lexical scoping, instead of raw textual manipulation, to connect documentation and code. This connection supports abstractions across the prose and code layers, and it enables a reliable association (e.g. via hyperlinks) of references in code fragments to specifications elsewhere in the documentation. For example, if @scr:code-elem|{@scheme[lambda]}| appears in document source within the lexical context of a @scheme[(require (for-label scheme/base))] declaration, then the rendered form @scheme[lambda] is hyperlinked to the documentation for @schememodname[scheme/base]---and not to the documentation of, say, @schememodname[lang/htdp-beginner], which exports a @htdp-lambda[] binding with a slightly different meaning. Moreover, the hyperlink will be correct even if @scr:code-elem|{@scheme[lambda]}| resides in a function that is used to generate documentation, and even if the calling context does not otherwise mention @scheme[scheme/base]. Such lexically scoped fragments of documentation are built on the same technology as Scheme's lexically scoped macros, and they provide the same benefits for documentation abstraction and composition. More generally, Scribble's connection to the implementation language provides a path to JavaDoc-like or even WEB-like extensions. For example, by ``including'' a source library, a Scribble program can extract documentation from the source, and bindings in the source can be reflected naturally as cross-references in the documentation. Similarly, a source program can use module-level imports to introduce and compose literate-programming forms; in other words, the module system acts as the language that Ramsey has suggested to organize the composition of @tt{noweb} extensions@~cite["noweb"]. Scribble's potential to span documentation-tool categories is a consequence of PLT Scheme's extensibility. Ordinarily, language extensibility would offer new challenges for JavaDoc-style tools, because a library's implementation might involve programmer-defined forms for definitions and imports. Scribble plugs into the same extensibility machinery, however, so new definition and import forms can implement corresponding extensions to the documentation system. Similarly, Scheme macros accommodate a WEB-like organization of a library's implementation, and the same macros can simultaneously organize the associated documentation. At present, Scribble has been developed primarily for stand-alone documentation. We have created only a prototype extension for JavaDoc-style extraction of API documentation, and we have not yet attempted to create WEB-style tool for literate programming. Nevertheless, the connection to source plays a crucial role in cross-referencing, in writing examples within the documentation, and in searching the documentation from within the programming environment. These capabilities point the way toward even more sophisticated extensions, and they illustrate the advantages of treating documentation as code.