#lang scribble/doc @(require "common.ss") @title[#:tag "srcdoc"]{In-Code Documentation} For some libraries, the programmer may want to write documentation with the source instead of in a separate document. To support such documentation, we have created a prototype Scheme/Scribble extension (which is currently used to document one library in the PLT Scheme distribution). Using this extension, the @schemeidfont{comics/string} module could be implemented as follows: @code-block|{ #reader scribble/reader #lang scheme/base (require scheme/contract scribble/srcdoc) (require/doc scheme/base scribble/manual) (define (louder s) (string-append s "!")) (provide/proc [louder ([str string?] . -> . string?) @{Adds ``!'' to the end of @scheme[str].}]) }| The @code-elem{#reader scribble/reader} line adds @lit["@"] notation to the default Scheme reader, and then @code-elem{#lang scheme/base} continues as usual for a Scheme module. The imported @schememodname[scribble/srcdoc] library binds @scheme[require/doc] and @scheme[provide/doc]. The @scheme[require/doc] form imports bindings into a ``documentation'' phase, and @scheme[provide/proc] form exports @scheme[louder], annotates it with a contract for run-time checking, and records the contract and description for inclusion in documentation. The description is an expression in the documentation phase; it is dropped by normal compilation of the module, but combined with the @scheme[require/doc] imports and inferred @scheme[(require (for-label ...))] imports to generate the module's documentation. The documentation part of this module is extracted using @scheme[include-extracted], which is provided by the @scheme[scribble/extract] module that cooperates with @scheme[scribble/srcdoc]. The extracted documentation might provide the entire text of the document directly, or it might be incorporated into a larger document: @code-block|{ ;; In string.scrbl: #lang scribble/doc @(require scribble/manual scribble/extract (for-label comics/string)) @title{Strings} @defmodule[comics/string] The @schememodname[comics/string] library provides functions for creating punchlines. @(include-extracted comics/string) }| The advantage of @scheme[scribble/srcdoc] and @scheme[scribble/extract] is that the description of the function is with the implementation, and the function contract need not be duplicated in the source and documentation. Similarly, the fact that @scheme[string?] in the contract gets its binding from @scheme[scheme/base] is specified once in the code and inferred for the documentation. At the same time, a phase separation prevents document-generating expressions from polluting the library's run-time execution, and the process of generating documentation need not execute the library that is documented. If this approach to documentation proves useful in PLT Scheme, then the syntax can be further improved to make the notation for convenient. For example, the combination @code-elem{#reader scribble/reader} followed by @code-elem{#lang scheme/base} is likely to be common, in which case it could be collapsed to @tt{#lang} @schemeidfont{scheme/base+scribble} simply by creating a new @schemeidfont{scheme/base+scribble} module. These techniques extend to the creation of WEB-like literate programming tools. In the same way that @code-elem{#lang scribble/doc} can lift out imports and definitions from the body of a module, a new @tt{#lang} @schemeidfont{scribble/lp} language could provide a module-body macro transformer that tangles code and weaves documentation. Moreover, due to the extensibility of its foundations, this literate-programming language would remain extensible through additional macros and libraries.