diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/literateprog/web.tex |
Initial commit
Diffstat (limited to 'web/literateprog/web.tex')
-rw-r--r-- | web/literateprog/web.tex | 1477 |
1 files changed, 1477 insertions, 0 deletions
diff --git a/web/literateprog/web.tex b/web/literateprog/web.tex new file mode 100644 index 0000000000..5d08fd7ed0 --- /dev/null +++ b/web/literateprog/web.tex @@ -0,0 +1,1477 @@ +% Page layout +\input webmac +\output{\setbox0=\box255}\eject % get rid of spurious WEBMAC page + +\font\man=manfnt scaled \magstep3 +\font\CompJtitle=ambx10 scaled\magstep4 +\font\CompJabstract=amb10 +\font\tenssb=amssmc10 +\font\tenss=amss10 +\font\tenssi=amssi10 +\font\eightss=helvetica at 8truebp +\font\eightssi=helveticai at 8truebp +\font\eightssb=helveticab at 8truebp +\font\eighttt=amtt8 +\font\ninerm=amr9 +\let\mc=\ninerm % medium caps for names like PASCAL + +\newdimen\pagewidth \newdimen\pageheight \newdimen\ruleht +\hsize=177mm \vsize=249mm +\parindent=1em % this is needed for WEB output +\pagewidth=\hsize \pageheight=\vsize \ruleht=1pt +\abovedisplayskip=11pt plus 3pt minus 8pt +\abovedisplayshortskip=0pt plus 3pt +\belowdisplayskip=11pt plus 3pt minus 8pt +\belowdisplayshortskip=6pt plus 3pt minus 3pt + +\newif\iftitle +\def\titlepage{\global\titletrue} % for pages without headlines + +\def\leftheadline{\hbox to \pagewidth{% + \vbox to 8pt{}\hss \eightrm D. E. KNUTH\hss}} +\def\rightheadline{\hbox to \pagewidth{% + \vbox to 8pt{}\hss \eightrm LITERATE PROGRAMMING\hss}} +\hoffset=-.25in \voffset=-.6in + +\newinsert\lefttop \newinsert\righttop +\count\lefttop=1000 \count\righttop=1000 +\dimen\lefttop=\maxdimen \dimen\righttop=\maxdimen +\skip\lefttop=25pt plus 3pt minus 3pt +\skip\righttop=\skip\lefttop +\def\leftfloat{\insert\lefttop\bgroup + \floatingpenalty=0 + \penalty0 + \vbox\bgroup} +\def\rightfloat{\insert\righttop\bgroup + \floatingpenalty=0 + \penalty0 + \vbox\bgroup} +\def\endfloat{\egroup\egroup} + +\def\onepageout#1{\shipout\vbox{ % here we define one page of output + \offinterlineskip % butt the boxes together + \vbox to 9mm{ % this part goes on top of the regular pages + \iftitle % the next is used for title pages + \global\titlefalse % reset the titlepage switch + \hbox to\pagewidth{\leaders\CJrule\hfill} + \else\ifodd\pageno \rightheadline\else\leftheadline\fi\fi + \vfill} % this completes the \vbox to 9mm + \vbox to \pageheight{ + #1 % now insert the main information + \boxmaxdepth=\maxdepth + } % this completes the \vbox to \pageheight + \baselineskip=7mm \lineskiplimit=0pt + \hbox to\pagewidth{% + \ifodd\pageno\hfil\tenss submitted to THE COMPUTER JOURNAL% + \tenssb\quad\folio + \else\tenssb\folio\quad + \tenss submitted to THE COMPUTER JOURNAL\hfil\fi} + } + \advancepageno} + +\output{\onepageout{\unvbox255}} + +\newbox\partialpage +\def\begindoublecolumns{\begingroup + \output={\global\setbox\partialpage=\vbox{\unvbox255}}\eject + \output={\doublecolumnout} \hsize=84mm \vsize=510mm} +\def\enddoublecolumns{\output={\balancecolumns}\eject + \endgroup \pagegoal=\vsize} + +\def\doublecolumnout{\dimen0=\pageheight + \advance\dimen0 by-\ht\partialpage \splittopskip=\topskip + \ifdim\ht\lefttop>0pt \setbox255=\vbox{\unvbox\lefttop + \setbox0=\lastbox\unvbox0\vskip\skip\lefttop\unvbox255}\fi + \setbox0=\vsplit255 to\dimen0 + \ifdim\ht\righttop>0pt \setbox255=\vbox{\unvbox\righttop + \setbox0=\lastbox\unvbox0\vskip\skip\righttop\unvbox255}\fi + \setbox2=\vsplit255 to\dimen0 + \onepageout\pagesofar + \unvbox255 \penalty\outputpenalty} +\def\pagesofar{\unvbox\partialpage + \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}} +\def\balancecolumns{\setbox0=\vbox{\unvbox255} \dimen0=\ht0 + \advance\dimen0 by\topskip \advance\dimen0 by-\baselineskip + \divide\dimen0 by2 \splittopskip=\topskip + {\vbadness=10000 \loop \global\setbox3=\copy0 + \global\setbox1=\vsplit3 to\dimen0 + \ifdim\ht3>\dimen0 \global\advance\dimen0 by1pt \repeat} + \setbox0=\vbox to\dimen0{\unvbox1} + \setbox2=\vbox to\dimen0{\unvbox3} + \pagesofar} + +\def\CJrule{\hrule height\ruleht} +\baselineskip=11pt +\parskip=0pt plus 1pt +\def\beginsection #1\par{\goodbreak\vskip9mm plus4mm minus 2mm + \vbox{\CJrule width \hsize \kern5pt} + \kern-3pt + \nointerlineskip + \leftline{\strut\bf#1} + \CJrule + \kern12pt\nobreak\noindent\ignorespaces} +\def\caption #1. #2.{\leftline{\def\TeX{T\kern-.2em\lower.5ex\hbox{E}X}% + \tenssb Figure #1.\enspace\tenss#2.}} + +\def\WEB{{\tt WEB}} +\def\PASCAL{{\mc PASCAL}} +\def\sec{{\tensy x}} +\def\<{$\langle\,$} +\def\>{$\,\rangle$} +\newbox\circlebox +\setbox\circlebox=\hbox{\man Y} +\def\encircle#1{\kern6pt\hbox to\wd\circlebox{\hss\tt#1\hss}\kern-\wd\circlebox + \raise10pt\copy\circlebox\kern6pt} + +\def\ttverbatim{\begingroup \tt \parindent=0pt \obeylines + \uncatcodespecials \catcode`/=0 \obeyspaces} +\let\endverbatim=\endgroup +{\obeyspaces\global\let =\ } % let active space = control space +\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials} +\def\cvdots{\kern3pt\qquad\smash\vdots} + +\newcount\refno \newif\ifshowit +\def\ref{\showittrue\makeref} +\def\silentref{\showitfalse\makeref} +\def\references{} % this will grow until it holds all the references +\def\makeref#1#2{\advance\refno by1 \edef#1{{\the\refno}}% + \toks0=\expandafter{\references}% + {\def\rm{\eightss}\def\sl{\eightssi}\def\bf{\eightssb}\def\tt{\eighttt}% + \def\TeX{T\kern-.2em\lower.5ex\hbox{E}\kern-.000em X}% + \xdef\references{\the\toks0 \noexpand\item{\the\refno.}#2\par}}% + \ifshowit\edef\next{\spacefactor=\the\spacefactor\space}% + $^{\the\refno}$\next\fi} +\hyphenation{Dijk-stra} +\hyphenchar\tentt=-1 % no hyphenation in the typewriter font + +\titlepage +\leftline{\kern13mm\CompJtitle Literate Programming} +\kern6mm +\CJrule +\kern4.5mm +\leftline{\kern13mm\bf Donald E. Knuth} +\kern2pt +\leftline{\kern13mm\eightrm Computer Science Department, Stanford University, + Stanford, CA 94305, USA} +\kern4mm +\CJrule +\kern6mm +\leftline{\kern13mm\vbox{\hsize=151mm\CompJabstract\noindent +The author and his associates have been experimenting for the past several +years with a programming language and documentation system called \WEB. +This paper presents \WEB\ by example, and discusses why the new +system appears to be an improvement over previous ones.}} +\bigskip\bigskip +\begindoublecolumns + +\beginsection A. INTRODUCTION + +The past ten years have witnessed substantial improvements in programming +methodology. This advance, carried out under the banner of ``structured +programming,'' has led to programs that are more reliable and easier to +comprehend; yet the results are not entirely satisfactory. My purpose +in the present paper is to propose another motto that may be appropriate +for the next decade, as we attempt to make further progress in the +state of the art. I believe that the time is ripe for significantly +better documentation of programs, and that we can best achieve this by +considering programs to be {\it works of literature}. Hence, my title: +``Literate Programming.'' + +Let us change our traditional attitude to the construction of programs: +Instead of imagining that our main task is to instruct a {\it computer\/} +what to do, let us concentrate rather on explaining to {\it human beings\/} +what we want a computer to do. + +The practitioner of literate programming can be regarded as an essayist, whose +main concern is with exposition and excellence of style. Such an author, +with thesaurus in hand, chooses the names of variables carefully and explains +what each variable means. He or she strives for a program that is +comprehensible because its concepts have been introduced in an order that +is best for human understanding, using a mixture of formal and informal +methods that re\"\i nforce each other. + +I dare to suggest that such advances in documentation are possible because +of the experiences I've had during the past several years while working +intensively on software development. By making use of several ideas that +have existed for a long time, and by applying them systematically in a +slightly new way, I've stumbled across a method of composing programs +that excites me very much. In fact, my enthusiasm is so great that I must warn +the reader to discount much of what I shall say as the ravings of a fanatic +who thinks he has just seen a great light. + +Programming is a very personal activity, so I can't be certain that what has +worked for me will work for everybody. Yet the impact of this new approach on +my own style has been profound, and my excitement has continued unabated +for more than two years. I~enjoy the new methodology so much that it is hard +for me to refrain from going back to every program that I've ever written +and recasting it in ``literate'' form. I~find myself unable to resist working +on programming tasks that I would ordinarily have assigned to student +research assistants; and why? Because it seems to me that at last I'm able +to write programs as they should be written. My programs are not only +explained better than ever before; they also are better programs, +because the new methodology encourages me to do a better job. For these +reasons I am compelled to write this paper, in hopes that my experiences +will prove to be relevant to others. + +I must confess that there may also be a bit of malice in my choice of +a title. During the 1970s I was coerced like everybody else into adopting +the ideas of structured programming, because I couldn't bear to be found +guilty of writing {\it unstructured\/} programs. Now I have a chance +to get even. By coining the phrase ``literate programming,'' I am imposing +a moral commitment on everyone who hears the term; surely nobody wants +to admit writing an {\it il{}literate\/} program. + +\beginsection B. THE \WEB\ SYSTEM + +I hope, however, to demonstrate in this paper that the title is not merely +wordplay. The ideas of literate programming have been embodied in a language +and a suite of computer programs that have been developed at Stanford +University during the past few years as part of my research on algorithms +and on digital typography. This language and its associated programs +have come to be known as the \WEB\ system. My goal in what follows is +to describe the philosophy that underlies \WEB, to present examples +of programs in the \WEB\ language, and to discuss what may be the future +implications of this work. + +I chose the name \WEB\ partly because it was one of the few three-letter +words of English that hadn't already been applied to computers. But as time +went on, I've become extremely pleased with the name, because I~think +that a complex piece of software is, indeed, best regarded as a {\it web\/} +that has been delicately pieced together from simple materials. We +understand a complicated system by understanding its simple parts, and by +understanding the simple relations between those parts and their immediate +neighbors. If we express a program as a web of ideas, we can emphasize +its structural properties in a natural and satisfying way. + +\WEB\ itself is chiefly a combination of two other languages: +(1)~a document formatting language and (2)~a programming language. +My prototype \WEB\ system uses \TeX\ as the document formatting +language and \PASCAL\ as the programming language, but the same +principles would apply equally well if other languages were +substituted. Instead of \TeX, one could use a language like Scribe +or Troff; instead of \PASCAL, one could use {\mc ADA}, {\mc ALGOL}, +{\mc LISP}, {\mc COBOL}, {\mc FORTRAN}, {\mc APL}, {\mc C}, etc., or +even assembly language. The main point is that \WEB\ is inherently +bilingual, and that such a combination of languages proves to be much +more powerful than either single language by itself. \WEB\ does not +make the other languages obsolete; on the contrary, it enhances them. + +I naturally chose \TeX\ to be the document formatting language, in the +first \WEB\ system, because \TeX\ is my own creation;\ref\TeXbook{D. E. Knuth, +{\sl The \TeX book}. Addison-Wesley, Reading, Mass., U.S.A. (1983).} +I wanted to acquire a lot of experience in harnessing \TeX\ to a variety +of different tasks. I~chose \PASCAL\ as the programming language because +it has received such widespread support from educational institutions all +over the world; it is not my favorite language for system programming, but +it has become a ``second language'' for so many programmers that it +provides an exceptionally effective medium of communication. Furthermore +\WEB\ itself has a macro-processing ability that makes \PASCAL's +limitations largely irrelevant. + +Document formatting languages are newcomers to the computing scene, but +their use is spreading rapidly. Therefore I'm confident that we will be +able to expect each member of the next generation of programmers to be +familiar with a document language as well as a programming language, +as part of their basic education. Once a person knows both of the +underlying languages, there's no trick at all to learning \WEB, because +the \WEB\ user's manual is fewer than ten pages long. + +A \WEB\ user writes a program that serves +as the source language for two different system routines. (See Figure~1.) +One line of processing is called {\it weaving\/} the web; it produces +a document that describes the program clearly and that facilitates program +maintenance. The other line of processing is called {\it tangling\/} the +web; it produces a machine-executable program. The program and its +documentation are both generated from the same source, so they are +consistent with each other. + +\bigskip +\centerline{\vbox{ + \halign{&\hss#\hss\cr + &&&\TeX\cr + \noalign{\vskip-4pt} + &&\encircle{TEX}&\enspace\rightarrowfill\enspace&\encircle{DVI}\cr + \multispan2\hfil\smash{\raise4pt\hbox{\tt WEAVE}\kern-1pt}$\nearrow$ \cr + \noalign{\vskip6pt} + \encircle{WEB}\cr + \noalign{\vskip6pt} + \multispan2\hfil\smash{\lower6pt\hbox{\tt TANGLE}\kern-1pt}$\searrow$ \cr + &&\encircle{PAS}&\enspace\rightarrowfill\enspace&\encircle{REL}\cr + \noalign{\vskip-2pt} + &&&\mc\ PASCAL\ \cr} + }} +\nobreak\medskip +\caption 1. Dual usage of a {\tt WEB} file. +\bigbreak + +Let's look at this process in slightly more detail. Suppose you have +written a \WEB\ program and put it into a computer text file called +{\tt COB.WEB} (say). To generate hardcopy documentation for your program, +you can run the {\tt WEAVE} processor; this is a system program that takes +the file {\tt COB.WEB} as input and produces another file {\tt COB.TEX} +as output. Then you run the \TeX\ processor, which takes {\tt COB.TEX} +as input and produces {\tt COB.DVI} as output. The latter file, +{\tt COB.DVI}, is a ``device-independent'' binary description of how +to typeset the documentation, so you can get printed output by applying +one more system routine to this file. + +You can also follow the other branch of Figure~1, by running the +{\tt TANGLE} processor; this is a system program that takes the file +{\tt COB.WEB} as input and produces a new file {\tt COB.PAS} as output. +Then you run the \PASCAL\ compiler, which converts {\tt COB.PAS} to +a binary file {\tt COB.REL} (say). Finally, you can run your program +by loading and executing {\tt COB.REL}. The process of ``compile, load, +and go'' has been slightly lengthened to ``tangle, compile, load, and go.'' + +\beginsection C. A COMPLETE EXAMPLE + +Now it's time for me to stop presenting general platitudes and to move on +to something tangible. Let us look at a real program that has been written +in \WEB. The numbered paragraphs that follow are the actual output of a +\WEB\ file that has been ``woven'' into a document; a computer has also +generated the indexes that appear at the program's end. If my claims for +the advantages of literate programming have any merit, you should be able +to understand the following description more easily than you could +have understood the same program when presented in a more conventional +way. However, I am trying here to explain the format of \WEB\ documentation +at the same time as I am discussing the details of a nontrivial algorithm, +so the description below is slightly longer than it would be if it were +written for people who already have been introduced to \WEB. + +\silentref\Dijk{O.-J.~Dahl, E.~W. Dijkstra, and C.~A.~R. Hoare, +{\sl Structured Programming}. Academic Press, London and New York (1972).} +\silentref\goto{D. E. Knuth, Structured programming with {\bf go to} +statements. {\sl Computing Surveys\/ \bf6}, 261--301 (1974).} + +Here, then, is the computer-generated output: + +\bigskip +\CJrule +\medskip +\begingroup +\def\prune\input webmac{\input primes.contents} +\def\Z#1#2#3{\line{\ignorespaces#1\ \dotfill\ {\tensy x}#2}} +\def\M#1.{\MN#1.\iftrue\medbreak\startsection\ignorespaces} +\def\firstmod{1} +\def\N#1.#2.{\MN#1.\iftrue\nobreak + \ifx\modno\firstmod\medskip\else\bigskip\fi + \CJrule\medbreak\startsection + {\bf\ignorespaces#2.\quad}\ignorespaces} +\def\inx{\par\medbreak + \def\:##1, {\par\hangindent2em\noindent##1:\kern1em} + \def\[##1]{$\underline{##1}$} + \rm \rightskip0pt plus2.5em \tolerance10000 \let\*=\lapstar + \hyphenpenalty10000 \parindent0pt} +\def\fin{\par\bigskip\CJrule\medbreak + \parfillskip0pt plus1fil + \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}} + \def\U{\note{Used in}} + \def\:{\par\hangindent 2em}\let\*=*} +\let\con=\par +\parskip=0pt +\expandafter\prune\input primes +\endgroup + +\beginsection D. HOW THE EXAMPLE WAS SPECIFIED + +Everything reproduced above, from the table of contents preceding the +program to the indexes of identifiers and section names at the end, +was generated by applying the program {\tt WEAVE} to a source file +{\tt PRIMES.WEB} written in the \WEB\ language. Let us now look at that +file {\tt PRIMES.WEB}, in order to get an idea of what a \WEB\ user +actually types. + +There's no need to show very much of {\tt PRIMES.WEB}, however, because +that file is reflected quite faithfully by the formatted output. Figure~2 +contains enough of the \WEB\ source to indicate the general flavor; +a reader who is familiar with the rudiments of \TeX\ will be able to +reconstruct all of {\tt PRIMES.WEB} by looking only at the formatted +output and Figure~2. + +\leftfloat +\ttverbatim +/hrule +/medskip +\font\ninerm=cmr9 +\let\mc=\ninerm % medium caps +\def\WEB{{\tt WEB}} +\def\PASCAL{{\mc PASCAL}} +\def\[{\ifhmode\ \fi$[\mkern-2mu[$} +\def\]{$]\mkern-2mu]$\ } +/cvdots +\hyphenation{Dijk-stra} +/medskip +@* Printing primes: An example of \WEB. +The following program is essentially the same +as Edsger Dijkstra's @^Dijkstra, Edsger@> +``first example of step-wise program +composition,'' found on pages 26--39 +of his {\sl Notes on Structured +Programming},$^\Dijk$ but it has been +translated into the \WEB\ language. @.WEB@> +/medskip +\[Double brackets will be used in what +follows to enclose comments relating to \WEB\ +/cvdots +an informal top-level description.\] +/medskip +@p @<Program to print the first thousand +prime numbers@> +/endverbatim +\medskip +\caption 2a. The beginning of {\tt PRIMES.WEB}. +\medskip +\hrule +\endfloat + +Figure 2a starts with \TeX\ commands (not shown in full) that make it +convenient to typeset double brackets $[\mkern-2mu[\ldots]\mkern-2mu]$ +and to give special typographic treatment to names like `\WEB' and `\PASCAL'. +A \WEB\ user generally begins by declaring such special aspects of the +document format; for example, if nonstandard fonts of type are needed, +they are usually stated first. It may also be necessary to specify the +correct hyphenation of non-English words that appear in the document. + +Then comes `{\tt@*}', which starts the program proper. \WEB\ uses the +symbol `{\tt@}' as an escape character for special instructions to the +{\tt WEAVE} and {\tt TANGLE} processors. Everything between such special +commands is either expressed in \TeX\ language or in \PASCAL\ language, +depending on the context. + +Each section of the program begins either with `{\tt@ }' (i.e., at-sign +and space) or `{\tt@*}' (i.e., at-sign and asterisk); \WEB\ supplies the +section numbers automatically. The latter case, `{\tt@*}', denotes a +{\it major section\/} of the program, for which a special title is given. +This title will appear in boldface type, and it will also appear in the +table of contents, and as a running headline on all pages of the +woven documentation until another major section begins. Each major section +starts at the top of a page. (Such page beginnings have been indicated +by horizontal lines in our example, because \WEB's normal output format +has been adapted to the format of this journal. The output of {\tt WEAVE} +usually has a lot more white space, and the individual lines of text +are usually quite a bit wider.) + +The lines that follow in Figure~2a show a few more \WEB\ instructions: +`{\tt@\char`^}' marks the beginning of an index entry to be set in roman +type; `{\tt@>}' marks the end of an argument to a \WEB\ command; +`{\tt@.}'\ marks the beginning of an index entry to be set in typewriter +type; `{\tt@p}' marks the beginning of the \PASCAL\ program; and `{\tt@<}' +marks the beginning of a top-level description, i.e., of a section +name in the \WEB\ program. + +\rightfloat +\ttverbatim +/hrule +/medskip +@ This program has no input, because we want +to keep it rather simple. The result of the +program will be to produce a list of the +first thousand prime numbers, and this list +will appear on the |output| file. +/medskip +Since there is no input, we declare the value +|m=1000| as a compile-time constant. The +program itself is capable of generating the +first |m| prime numbers for any positive |m|, +as long as the computer's finite limitations +are not exceeded. +/medskip +\[The program text below specifies the +``expanded meaning'' of `\X2:Program to print +$\ldots$ numbers\X'; notice that it involves +the top-level descriptions of three other +sections. When those top-level descriptions +are replaced by their expanded meanings, a +syntactically correct \PASCAL\ program will +be obtained.\] +/medskip +@<Program to print...@>= +program print_primes(output); +const @!m=1000; +@<Other constants of the program@>@; +var @<Variables of the program@>@; +begin @<Print the first |m| prime numbers@>; +end. +/endverbatim +\medskip +\caption 2b. The \WEB\ code that generated \sec2. +\ttverbatim +/bigskip +/hrule +/medskip +@ In order to keep this program reasonably +free of notations that are uniquely +\PASCAL esque, \[and in order to illustrate +/cvdots +The first three macro definitions here are +parametric; the other two are simple.\] +/medskip +@d print_string(#)==write(#) + {put a given string into the |output| file} +@d print_integer(#)==write(#:1) + {put a given integer into the |output| + file, in decimal notation, using only as + many digit positions as necessary} +@d print_entry(#)==write(#:ww) + {like |print_integer|, but + |ww| character positions are filled, + inserting blanks at the left} +@d new_line==write_ln + {advance to a new line in the |output| file} +@d new_page==page + {advance to a new page in the |output| file} +/endverbatim +\medskip +\caption 2c. The \WEB\ code that generated \sec6. +\medskip +\hrule +\endfloat + +Figure 2b immediately follows Figure~2a in the \WEB\ file. This material +is what generated \sec2 of the documentation, and it illustrates the +bilingual nature of \WEB: The commentary at the beginning of each section +is typed in \TeX\ language, and the program text at the end is typed +in \PASCAL\ language. + +Language-switching between \TeX\ and \PASCAL\ is occasionally desirable. +For example, when you refer to technical details about the program, you +usually want to describe them in \PASCAL, hence you want {\tt WEAVE} to format +them with the typographic conventions it uses for \PASCAL\ programs. +Conversely, when you put comments in a \PASCAL\ program, you want +the text of those comments to be formatted by \TeX\ in the normal way. +\WEB\ files use vertical bars to introduce \PASCAL\ formatting in the +midst of \TeX\ formatting; for example, Figure~2b says `{\tt the +|output| file}' in order to typeset `the \\{output} file'. + +The program text in Figure~2b begins with `{\tt@<}' instead of with the +`{\tt@p}' command used in Figure~2a, because the program text in~\sec2 +is the expansion of a specific top-level description. Notice that the +top-level description has been abbreviated to `{\tt@<Program to print...@>}'. +Since the names of sections tend to be rather long, it is a nuisance to +type them in full each time; \WEB\ allows you to type `{\tt...}'\ after you +have given enough text to identify the remainder uniquely. + +The `{\tt@!}'\ operation in the program text of Figure~2b governs the +underlining of index entries. The `{\tt@;}'\ specifies an invisible symbol +that has the effect of a semicolon in \PASCAL\ syntax. Commands such as these +are comparatively unimportant, but they are available for polishing up +the final documentation when you want to maintain fine control. + +Figure 2c shows key portions of the \WEB\ text that generated \sec6. +Notice that the command `{\tt@d}' introduces a macro definition. +All features of \WEB\ that appear in our example program are illustrated +in Figures 2a, 2b, and~2c; the remainder of {\tt PRIMES.WEB} simply +uses the same conventions again and again. In fact, most of the \WEB\ +file is much simpler than the examples shown here; Figure~2 has +illustrated only the difficult parts. + +\beginsection E. THE TANGLED OUTPUT + +Figure 3 shows the \PASCAL\ program {\tt PRIMES.PAS} that results when +{\tt TANGLE} is applied to {\tt PRIMES.WEB}. This program is not intended +for human consumption---it's only supposed to be readable by a \PASCAL\ +compiler---so {\tt TANGLE} does not go to great pains to produce a +beautiful format. Notice that underlines have been removed from the +identifier names, and that all of the letters have been converted to +uppercase (except in strings); {\tt TANGLE} tries to produce a format +that will be acceptable to a standard \PASCAL\ compiler. + +{\tt TANGLE} removes all of the commentary in the \WEB\ file, but it +inserts new comments of its own. If for some reason you need +to correlate the tangled \PASCAL\ code with the woven documentation, +you can find the program text for, say, \sec8 by looking between +the comments `{\tt\char`\{8:\char`\}}' and `{\tt\char`\{:8\char`\}}'. + +A comparison of Figure~3 to Figure~2 should make it clear why the +{\tt TANGLE} processor has acquired its name. + +\rightfloat +\ttverbatim +/hrule +/medskip +{1:}{2:}PROGRAM PRINTPRIMES(OUTPUT); +CONST M=1000;{5:}RR=50;CC=4;WW=10;{:5}{19:} +ORDMAX=30;{:19}VAR{4:} +P:ARRAY[1..M]OF INTEGER;{:4}{7:} +PAGENUMBER:INTEGER;PAGEOFFSET:INTEGER; +ROWOFFSET:INTEGER;C:0..CC;{:7}{12:}J:INTEGER; +K:0..M;{:12}{15:}JPRIME:BOOLEAN;{:15}{17:} +ORD:2..ORDMAX;SQUARE:INTEGER;{:17}{23:} +N:2..ORDMAX;{:23}{24:} +MULT:ARRAY[2..ORDMAX]OF INTEGER;{:24} +BEGIN{3:}{11:}{16:}J:=1;K:=1;P[1]:=2;{:16} +{18:}ORD:=2;SQUARE:=9;{:18}; +WHILE K<M DO BEGIN{14:}REPEAT J:=J+2;{20:} +IF J=SQUARE THEN BEGIN ORD:=ORD+1;{21:} +SQUARE:=P[ORD]*P[ORD];{:21}{25:} +MULT[ORD-1]:=J;{:25};END{:20};{22:}N:=2; +JPRIME:=TRUE; +WHILE(N<ORD)AND JPRIME DO BEGIN{26:} +WHILE MULT[N]<J DO MULT[N]:=MULT[N]+P[N]+P[N] +;IF MULT[N]=J THEN JPRIME:=FALSE{:26};N:=N+1; +END{:22};UNTIL JPRIME{:14};K:=K+1;P[K]:=J; +END{:11};{8:}BEGIN PAGENUMBER:=1; +PAGEOFFSET:=1; +WHILE PAGEOFFSET<=M DO BEGIN{9:} +BEGIN WRITE('The First ');WRITE(M:1); +WRITE(' Prime Numbers --- Page '); +WRITE(PAGENUMBER:1);WRITELN;WRITELN; +FOR ROWOFFSET:=PAGEOFFSET TO PAGEOFFSET+RR-1 +DO{10:} +BEGIN FOR C:=0 TO CC-1 DO IF ROWOFFSET+C*RR<= +M THEN WRITE(P[ROWOFFSET+C*RR]:WW);WRITELN; +END{:10};PAGE;END{:9}; +PAGENUMBER:=PAGENUMBER+1; +PAGEOFFSET:=PAGEOFFSET+RR*CC;END;END{:8}{:3}; +END.{:2}{:1} +/endverbatim +\medskip +\caption 3. PASCAL program generated from the \WEB\ file. +\medskip +\hrule +\endfloat + +\beginsection F. THE WOVEN OUTPUT + +I mentioned earlier that {\tt WEAVE} is a program that converts a file +like {\tt PRIMES.WEB} into a file {\tt PRIMES.TEX} that is a syntactically +correct source file for \TeX. Figure~4 gives a sampling of {\tt PRIMES.TEX}, +which is even more unreadable than {\tt PRIMES.PAS}. The instructions that +cause \TeX\ to produce formatted \PASCAL\ programs, with appropriate +typefaces and indentation, etc., are somewhat complex because they are +supposed to give decent results regardless of the page size. + +There is no need to discuss Figure~4 further in the present paper, because +the details of ``pretty printing'' are not relevant to my main theme. +I have shown this much of {\tt PRIMES.TEX} only to make the point that +it is nice to have a program like {\tt WEAVE} to do all the formatting; +computer programs are not easy to typeset. + +\leftfloat +\ttverbatim +/hrule +/medskip +\input webmac +\font\ninerm=amr9 +/cvdots +syntactically correct \PASCAL\ program will +be obtained.\] +/medskip +\Y\P$\4\X2:Program to print the first +thousand prime numbers\X\S$\6 +\4\&{program}\1\ \37$\\{print\_primes}(% +\\{output})$;\6 +\4\&{const} \37$\|m=1000$;\5 +\X5:Other constants of the program\X\6 +\4\&{var} \37\X4:Variables of the program\X\6 +\&{begin} \37\X3:Print the first \|m prime +numbers\X;\6 +\&{end}.\par +\U section~1.\fi +/cvdots +The first three macro definitions here are +parametric; the other two are simple.\] +/medskip +\Y\P\D \37$\\{print\_string}(\#)\S\\{write}(% +\#)$\C{put a given string into the % +\\{output} file}\par +/cvdots +\inx +\:{Bertrand, Joseph, postulate}, 21. +\:\\{boolean}, 15. +/cvdots +\:\.{WEB}, 1. +\:\\{write}, 6. +\:\\{write\_ln}, 6. +\:\\{ww}, \[5], 6. +\fin +/cvdots +\:\X4, 7, 12, 15, 17, 23, 24:Variables of +the program\X +\U section~2. +\con +/endverbatim +\medskip +\caption 4. \TeX\ program generated from the \WEB\ file. +\medskip +\hrule +\endfloat + +\beginsection G. ADDITIONAL BELLS AND WHISTLES + +A system like \WEB\ can be successful only if it is capable of handling +large programs as well as small ones, and only if it is complete enough +to take care of all the practical requirements that arise when many +different kinds of programs are considered. A small example like +{\tt PRIMES.WEB} is a satisfactory vehicle for illustrating the general +ideas, but it cannot be convincing as a demonstration of \WEB's ability +to produce quality software in the ``real world.'' My original design +of \WEB\ in September, 1981, was followed by a year of extensive +experiments, so that by the time Version~1 was released in +September, 1982, I could be fairly confident that the language was +reasonably complete. Since then only one or two small extensions +have proved to be necessary; and although numerous enhancements can +easily be imagined, I believe that a useful stopping point for a +working system called {\tt WEB83} has been reached. + +A full description of {\tt WEB83} appears in a Stanford report,\ref\WEBman% +{D. E. Knuth, {\sl The \WEB\kern-2pt\ System of Structured Documentation}. +Stanford Computer Science Report CS980 (September 1983).} +which also contains the complete \WEB\ programs for {\tt WEAVE} and +{\tt TANGLE}. The full language contains only a few features that +do not show up in the {\tt PRIMES} example considered above: + +\def\nindent#1{\noindent\hbox to\parindent{#1)\hfil}\ignorespaces} +\smallskip +\nindent1 There are facilities to override {\tt WEAVE}'s +automatic formatting of \PASCAL\ programs. For example, it is +possible to force a statement to begin on a new line, or to force +several statements to appear on the same line, or to suggest +a desirable breakpoint in the middle of a long expression. In +unusual cases, {\tt WEAVE} must parse program fragments that +are not syntactically complete---for example, there may be a +{\bf begin} without a matching {\bf end}---so a \WEB\ user must +be given a chance to control the results. Furthermore there is a +facility for changing {\tt WEAVE}'s formatting rules by declaring +that a certain identifier should be treated as a certain \PASCAL\ +reserved word, or by declaring that a certain reserved word +should be treated as an ordinary identifier. + +\smallskip +\nindent2 There is a way to force {\tt TANGLE} to omit a +space between two adjacent pieces of text, so that a name +like `\\{x3}' can be manufactured from `\|x' and `\\3'. Similarly, +there is a way to pass an arbitrary sequence of characters through +{\tt TANGLE} so that the same sequence will appear ``verbatim'' in +the \PASCAL\ file; and there is a way to force beginning-of-line +in that file. The latter extensions have proved to be necessary +to deal with various nonstandard conventions of different \PASCAL\ compilers. +When a comment in braces is sent to the \PASCAL\ file, {\tt TANGLE} +is careful not to introduce further braces inside the comment. + +\smallskip +\nindent3 There are facilities for octal and hexadecimal constants in \WEB\ +thees. {\tt TANGLE} converts such constants to decimal form; {\tt WEAVE} gives +them an appropriate typographic treatment. + +\smallskip +\nindent4 There is a facility for dealing with alphabetic constants. +When a program contains a double-quoted character like {\tt"A"}, +{\tt TANGLE} converts this to an integer between 0 and~127 that +equals the corresponding {\mc ASCII} code (in this case 65). +The use of {\mc ASCII} code facilitates the construction of software +that is readily portable from one machine to another, independent of +the actual character set in use. + +\smallskip +\nindent5 Furthermore, if a double-quoted constant is a string +of several characters, like {\tt"cat"}, {\tt TANGLE} converts it +into a unique integer that is 128 or more. A special {\it string pool +file\/} is written, containing all of the strings that have been +specially encoded in this way. I have used this general mechanism only +in large programs, but experience has shown that it makes quite a +nice substitute for the string-processing capabilities that \PASCAL\ +lacks. (Incidentally, I noticed after several months that a program +needs to have some indication that the string-pool file it is reading +contains the same strings that {\tt TANGLE} generated when the program +itself was tangled. Therefore a ``check sum'' is included in the +string pool file; each program is able to refer to its own check sum +and to compare it with the value in the file. This check-sum extension +was one of the last features to be added to \WEB.) + +\smallskip +\nindent6 The {\tt PRIMES} example illustrates macros with +parameters and macros without parameters. \WEB\ also allows ``numeric'' +macros, which are small integer constants; {\tt TANGLE} is capable of +doing simple arithmetic on such constants. This feature of \WEB\ was +introduced specifically to overcome \PASCAL's unfortunate inability to +do compile-time arithmetic. For example, it is impossible to have a +\PASCAL\ array whose bounds are `$0\to n-1$', or to write +`$20+3:$' as the label of one of the cases in `{\bf case} $x+y$'; +\WEB's numeric macros make it possible for {\tt TANGLE} to +preprocess such constants. + +\beginsection H. OCCAM'S RAZOR + +I would also like to mention several things that were intentionally left +out of \WEB, since I have tried to keep the language as simple as I could. + +There are no ``conditional macros,'' nor does {\tt TANGLE} +evaluate Boolean expressions that might influence the +output. I~found that everything I needed could be done +satisfactorily by commenting out the optional code. + +For example, a system program is often designed to gather statistics about +its own operation, but such statistics-gathering is pointless unless someone +is actually going to use the results. In order to make the instrumentation +code optional, I include the word `{\bf stat}' just before any special +code for statistics, and `{\bf tats}' just after such code; and I tell +{\tt WEAVE} to regard {\bf stat} and {\bf tats} as if they were {\bf begin} +and {\bf end}. But {\bf stat} and {\bf tats} are actually simple macros. +When I do want to gather the statistics, I define {\bf stat} and {\bf tats} to +be null; but in a production version of the software, I make {\bf stat} +expand to~`{\tt@\char`\{}' and {\bf tats} expand to~`{\tt@\char`\}}', +where {\tt@\char`\{} and {\tt@\char`\}} are special braces that {\tt TANGLE} +does not remove. Thus the optional code appears as a harmless comment in +the \PASCAL\ program. + +\WEB's macros are allowed to have at most one parameter. Again, I did this +in the interests of simplicity, because I noticed that most applications +of multiple parameters could in fact be reduced to the one-parameter case. +For example, suppose that you want to define something like +$$\hbox{\tt mac(\#1,\#2) == m[\#1*r+\#2]}$$ +which \WEB\ doesn't permit. You can get essentially the same result +with two one-parameter macros +$$\vbox{\halign{\tt#\hfil\cr +mac\char`\_tail(\#) == \#]\cr +mac(\#) == m[\#*r+mac\char`\_tail\cr}}$$ +since, e.g., `{\tt mac(a)(b)}' will expand into `{\tt m[a*r+b]}'. + +Here is another example that indicates some of the surprising generality +of one-parameter macros: Consider the two definitions +$$\vbox{\halign{\tt#\hfil\cr +define two\char`\_cases(\#)==case j of\cr +\ \ \ \ \ \ \ \ \ \ \ \ \ 1:\#(1); 2:\#(2); end\cr +define reset\char`\_file(\#)==reset(file@\&\#)\cr}}$$ +where `{\tt@\char`\&}' in the second definition is the concatenation operation +that pastes two texts together. You can now say +$$\hbox{\tt two\char`\_cases(reset\char`\_file)}$$ +and the resulting \PASCAL\ output will be +$$\vbox{\halign{\tt#\hfil\cr +case j of\cr +1:reset(file1);\cr +2:reset(file2);\cr +end\cr}}$$ +In other words, the name of one macro can usefully be a parameter to +another macro. This particular trick makes it possible to live with +\PASCAL\ compilers that do not allow arrays of files. + +\beginsection I. PORTABILITY + +One of the goals of my \TeX\ research has been to produce portable +software, and the {\tt WEB} system has been extremely helpful in this +respect. Although my own work is done on a DEC-10 computer with +Stanford's one-of-a-kind operating system, the software developed +with \WEB\ has already been transported successfully to a wide +variety of computers made by other manufacturers (including IBM, +Control Data, XEROX, Hewlett-Packard), and to a variety +of different operating systems for those machines. To my knowledge, +no other software of such complexity has ever been transported to +so many different machines. It seems likely that \TeX\ will soon be +operating on all but the smallest of the world's computer systems. + +To my surprise, the main bottleneck to portability of the \TeX ware +has been the lack of suitable \PASCAL\ compilers, because \PASCAL\ has +often been implemented without system programming in mind. Anybody +who has a decent \PASCAL\ compiler can install \WEB\ (and all programs +written in \WEB) without great difficulty, essentially as follows: + +\smallskip +\item{1)} Start with the three files {\tt WEAVE.WEB}, {\tt TANGLE.WEB}, and +{\tt TANGLE.PAS}. (The programs have not been copyrighted, so +these files are not difficult to obtain.) + +\item{2)} Run {\tt TANGLE.PAS} through your \PASCAL\ compiler to +get a working {\tt TANGLE} program. + +\item{3)} Check your {\tt TANGLE} by applying it to {\tt TANGLE.WEB}; +your output file should match {\tt TANGLE.PAS}. + +\item{4)} Apply your {\tt TANGLE} to the file {\tt WEAVE.WEB}, obtaining +{\tt WEAVE.PAS}; then apply \PASCAL\ to {\tt WEAVE.PAS} and you'll +have a working {\tt WEAVE} system. + +\item{5)} The same process applies to any software written in \WEB, +notably to \TeX\ itself. (However, you need fonts and suitable output +equipment in order to make proper use of \TeX; that may be another +bottleneck.) Once you have \TeX\ working, you can apply {\tt WEAVE} +and \TeX\ to your \WEB\ files, thereby getting program documents +as illustrated above. + +\smallskip\noindent +Notice that a {\tt TANGLE.PAS} file is needed in order to get this +``bootstrapping'' process started. If you have just {\tt WEAVE.WEB} +and {\tt TANGLE.WEB}, you can't do the first step. + +However, anybody who has looked seriously into the question of software +portability will realize that my comments in the preceding paragraphs +have been oversimplified. I have glossed over some serious +problems that arise: Character sets are different; file naming conventions +are different; special conventions are needed to interact with a user's +terminal; data is packed differently on different machines; floating-point +arithmetic is always nonstandard and sometimes nonexistent; users want +``friendly'' interaction with existing programs for editing and spooling; +etc., etc. Furthermore, many of the world's \PASCAL\ compilers are incredibly +bizarre. Therefore it is quite na\"\i ve to believe that a single program +{\tt TANGLE.PAS} could actually work on very many different machines, or +even that one single source file {\tt TANGLE.WEB} could be adequate; some +system-dependent\kern-.5pt\kern.5pt\ changes are inevitable. + +The \WEB\ system caters to system-dependent changes in a simple but surprisingly +effective way that I neglected to mention when I listed its other features. +Both {\tt TANGLE} and {\tt WEAVE} are designed to work with +{\it two\/} input files, not just one: In addition to a \WEB\ source file +like {\tt TEX.WEB}, there is also a ``change file'' {\tt TEX.CH} that +contains whatever changes are needed to customize \TeX\ for a particular +system. (Similarly, the source files {\tt WEAVE.WEB} and {\tt TANGLE.WEB} +are accompanied by {\tt WEAVE.CH} and {\tt TANGLE.CH}.) + +Here's how change files work: Each change has the form ``replace +$x_1\ldots x_m$ by $y_1\ldots y_n$,'' for some $m\ge 1$ and $n\ge0$; +here $x_i$ and~$y_j$ represent lines in the change file. +The {\tt WEAVE} and {\tt TANGLE} programs +read data from the \WEB\ input file until finding a line that matches +$x_1$; this line, and the $m-1$ following lines, are replaced by +$y_1\ldots y_n$. An error message is given if the $m$ lines replaced did +not match $x_1\ldots x_m$ perfectly. + +For example, the program {\tt PRIMES.WEB} invokes a \\{page} procedure to +begin a new page; but \\{page} was not pres\-ent in Wirth's original \PASCAL\ +and it is defined rather vaguely in the \PASCAL\ standard. Therefore +a system-dependent change may be needed here. A change file {\tt +PRIMES.CH} could be made by copying the line +$$\hbox{\tt @d new\char`\_page==page}$$ from +Figure~2c and specifying one or more appropriate replacement lines. + +The program {\tt TANGLE} itself contains about 190 sections, and a +typical installation will have to change about 15 of these. If you +want to transport {\tt TANGLE} to a new environment, you therefore +need to create a suitable file {\tt TANGLE.CH} that modifies 15~or~so parts +of {\tt TANGLE.WEB}. (Examples of {\tt TANGLE.CH} are provided to +all people who receive {\tt TANGLE.WEB}, so that each implementor has +a model of what to do.) You need to insert your changes by hand into +{\tt TANGLE.PAS}, until you have a {\tt TANGLE} program that works +sufficiently well to support further bootstrapping. But you never +actually change the master file {\tt TANGLE.WEB}. + +This approach has two important advantages. First, the same +master file {\tt TANGLE.WEB} is used by everybody, and it +contains the basic logic of {\tt TANGLE} that really defines the +essence of tangling. The system-dependent changes do not affect +any of the subtle parts of {\tt TANGLE}'s control structures or +data structures. Second, when the official {\tt TANGLE} has been +upgraded to a newer version, a brand new {\tt TANGLE.WEB} will +almost always work with the old {\tt TANGLE.CH}, since changes +are rarely made to the system-dependent parts. In other words, +this dual-input-file scheme works when the \WEB\ file is constant +and the {\tt CH} file is modified, and it also works when the +{\tt CH} file is constant but the \WEB\ file is modified. + +Change files were added to \WEB\ about three months after the system was +initially designed, based on our initial experiences with people who had +volunteered to participate in portability experiments. We realized +about a year later that {\tt WEAVE} could be modified so that +only the changed parts of a program would (optionally) be printed; thus, +it's now possible to document the changes by listing only the sections +that are actually affected by the {\tt CH} file that {\tt WEAVE} has +processed. We also generalized the original format of {\tt CH} files, +which permitted only changes that extended to the end of a section. These +two important ideas were among the final enhancements incorporated into +{\tt WEB83}. + +\beginsection J. PROGRAMS AS WEBS + +When I first began to work with the ideas that eventually became the +\WEB\ system, I thought that I would be designing a language for ``top-down'' +programming, where a top-level description is given first and successively +refined. On the other hand I knew that I often created major parts +of programs in a ``bottom-up'' fashion, starting with the definitions of +basic procedures and data structures and gradually building more and +more powerful subroutines. I had the feeling that top-down and bottom-up +were opposing methodologies: one more suitable for program exposition +and the other more suitable for program creation. + +But after gaining experience with \WEB, I have come to realize that there is +no need to choose once and for all between top-down and bottom-up, because +a program is best thought of as a web instead of a tree. A hierarchical +structure is present, but the most important thing about a program is +its structural relationships. A complex piece of software consists of +simple parts and simple relations between those parts; the programmer's +task is to state those parts and those relationships, in whatever order +is best for human comprehension---not in some rigidly determined +order like top-down or bottom-up. + +When I'm writing a longish program like {\tt TANGLE.WEB} or {\tt WEAVE.WEB} +or {\tt TEX.WEB}, I invariably have strong feelings about what part of the +whole should be tackled next. For example, I'll come to a point where I need +to define a major data structure and its conventions, before I'll feel +happy about going further. My experiences have led me to believe that a +person reading a program is, likewise, ready to comprehend it by +learning its various parts in approximately the order in which it +was written. The {\tt PRIMES.WEB} example illustrates this principle on +a small scale; the decisions that Dijkstra made as he composed the original +program$^\Dijk$ appear in the \WEB\ documentation in the same order. + +Top-down programming gives you a strong idea of where you are going, but +it forces you to keep a lot of plans in your head; suspense builds up +because nothing is really nailed down until the end. Bottom-up programming +has the advantage that you continually wield a more and more powerful +pencil, as more and more subroutines have been constructed; but it forces +you to postpone the overall program organization until the last minute, +so you might flounder aimlessly. + +When I tear up the first draft of a program and start over, my second draft +usually considers things in almost the same order as the first one did. +Sometimes the ``correct'' order is top-down, sometimes it is bottom-up, +and sometimes it's a mixture; but always it's an order that makes sense on +expository grounds. + +Thus the \WEB\ language allows a person to express programs +in a ``stream of consciousness'' order. {\tt TANGLE} is able to scramble +everything up into the arrangement that a \PASCAL\ compiler demands. This +feature of \WEB\ is perhaps its greatest asset; it makes a \WEB-written +program much more readable than the same program written purely in +\PASCAL, even if the latter program is well commented. And the fact that there's +no need to be hung up on the question of top-down versus bottom-up---since +a programmer can now view a large program as a web, to be explored in +a psychologically correct order---is perhaps the greatest lesson I have +learned from my recent experiences. + +Another surprising thing that I learned while using \WEB\ was that +traditional programming languages had been causing me to write inferior +programs, although I hadn't realized what I was doing. My original idea was that +\WEB\ would be merely a tool for documentation, but I actually found that +my \WEB\ programs were better than the programs I had been writing +in other languages. How could this be? + +Well, imagine that you are writing a small subroutine that updates part +of a data structure, and suppose that the updating takes only +one or two lines of code. In practical programs, there's often something +that can go wrong, if the user's input is incorrect, so the subroutine +has to check that the input is correct before doing the update. +Thus, the subroutine has the general form +$$\vbox{\halign{#\hfil\cr +\&{procedure} \\{update};\cr +\&{begin if} \<input data is invalid\> \&{then}\cr +\quad \<Issue an error message and try to recover\>;\cr +\<Update the data structure\>;\cr +\&{end}.\cr}}$$ +A subtle phenomenon occurs in traditional programming languages: While +writing the program for `\<Issue an error message and try to recover\>', +a programmer subconsciously tries to get by with the fewest possible +lines of code, since the program for `\<Update the data structure\>' is +quite short. If an extensive error recovery is actually programmed, the +subroutine will appear to have error-message printing as its main purpose. +But the programmer knows that the error is really an exceptional case that +arises only rarely; therefore a lengthy error recovery doesn't look right, +and most programmers will minimize it (without realizing that they are doing +so) in order to make the subroutine's appearance match its intended behavior. +On the other hand when the same task is programmed with \WEB, the purpose +of \\{update} can be shown quite clearly, and the possibility of error +recovery can be reduced to a mere mention when \\{update} is defined. +When another section entitled `\<Issue an error message and try to +recover\>' is subsequently written, the whole point of that section is to do +the best error recovery, and it becomes quite natural to write a better program +as a result. + +This fact---that \WEB\ allows you to let each part of the program have +its appropriate size, without distorting the readability of other parts---means +that good programmers find their \WEB\ programs better than their \PASCAL\ +programs, even though their \PASCAL\ programs once looked like the work +of an expert. + +\beginsection K. STYLISTIC ISSUES + +I found that my style of using \WEB\ evolved quite a bit during the first +year. The general format, in which each section beings with commentary and +ends with a formal program fragment, is extremely versatile; you have the +freedom to say anything you want, yet you must make a decision about how +you'll do it. I imagine that different programmers will converge to +quite different styles, but I would like to note down some of the things +that have seemed to work best for me. + +Consider first the question of macros versus section names. A named section, +like `\<Issue an error message and try to recover\>', is essentially the +same as a parameterless macro; \WEB\ provides both. I prefer to use +parameterless macros for ``small'' things that can be embodied in a word +or two, but named sections for longer portions of the program that +merit a fuller description. + +I usually start the name of a section with an imperative verb, but I give +a declarative commentary at the beginning of a section. Thus, +{\tt PRIMES.WEB} says `{\bf 8.}~Now that appropriate $\ldots$ +\X8:Print table $p$\X$\;\S\;$\dots\thinspace'; I wouldn't do the opposite +and say `{\bf8.}~Print the table. \X8:Code for printing\X$\;\S\;$\dots'. + +The name of a section (enclosed in angle brackets) should be long enough +to encapsulate the essential characteristics of the code in that section, +but it should not be too verbose. I found very early that it would be a +mistake to include all of the assumptions about local and global variables +in the name of each section, even though such information would strictly +be necessary to isolate that section as an independent module. The trick is +to find a balance between formal and informal exposition so that a reader +can grasp what is happening without being overwhelmed with detail.\ref\Naur% +{P. Naur, Formalization in program development. {\sl BIT\/ \bf22}, +437--453 (1982).} + +Another lesson I learned early in the game was that the name of a section +should explicitly mention any nonstandard control structures, even though +its data structures can often be left implied. Furthermore, if the control +flow is properly explained, you can avoid the usual errors associated +with \&{goto} statements; such statements can safely be introduced in +a restrained but natural manner. + +For example, \sec14 of the prime-printing example could be reprogrammed as +follows, using `\&{loop}' as a macro abbreviation for `\&{while} \\{true} +\&{do}': +$$\vbox{\halign{\hbox to\hsize{#\hfil}\cr +\X14:Increase $j$ until it is the next prime number\X$\;\S$\cr +\quad\&{loop begin} $j\K j+2$;\cr +\qquad\X20:Update variables that depend on $j$\X;\cr +\qquad\X22:If $j$ is prime, \&{goto} \\{found}\X;\cr +\qquad\&{end};\cr +\\{found}:\cr}}$$ +With this change, \sec22 could become +$$\vbox{\halign{\hbox to\hsize{#\hfil}\cr +\X22:If $j$ is prime, \&{goto} \\{found}\X$\;\S$\cr +\quad$n\K2$;\cr +\quad\&{while} $n<\\{ord}$ \&{do}\cr +\qquad\&{begin} \X26:If $p[n]$ is a factor of $j$, \&{goto} \\{not\_found}\X;\cr +\qquad$n\K n+1$;\cr +\qquad\&{end};\cr +\quad\&{goto} \\{found};\cr +\\{not\_found}:\cr}}$$ +if \sec26 changes in the obvious way. The resulting program will be more +efficient on most machines; and I believe that it is actually easier to +read and to write, in spite of the fact that two \&{goto} statements +appear, because the labels have been used with appropriate interpretations +of their abstract significance. + +Of course, \PASCAL\ makes it difficult to use \&{goto} statements, +because Wirth decided that labels should be numeric, and that they +should be declared in advance. If I were to introduce the \&{goto} +statements as suggested, I would have to define numeric macros +\\{found} and \\{not\_found}, and I would have to insert +`\&{label} \\{found}, \\{not\_found}' into the program at the right place. +Such extra work is a bit of a nuisance, but it can be done in \WEB\ without +spoiling the exposition. + +\PASCAL\ has a few other misfeatures that prove to be inconvenient with +respect to \WEB\ exposition. The worst of these is the inability to +declare local variables in the midst of a program or procedure. For +example, a programmer often finds it most natural to define an integer +variable when a \&{for} loop is introduced, but the rules of \PASCAL\ +insist that such a variable be declared rather far away from +that \&{for} loop. My \WEB\ programs overcome this problem by having +sections like `\<Local variables for \\{xyzzy}\>' whenever there's a +rather lengthy procedure `\\{xyzzy}' whose local variables should not +be declared all at once. But when a procedure is short, say only half +a dozen sections long, there's usually no harm in declaring its local +variables in \PASCAL\ style, because the entire text of the procedure will +tend to appear on one or two adjacent pages of the documentation. + +Another slightly awkward aspect of \PASCAL\ is its treatment of semicolons. +If you look closely at the prime-number example, you'll see that I had to +be a bit careful about where I put semicolons; sometimes they occur at the +end of the expanded text of a section, but usually they don't. With +a little self discipline, a person can learn to do this quite satisfactorily, +but it is a nuisance until you get used to it. + +\beginsection L. ECONOMIC ISSUES + +What does it cost to use \WEB? Let's look first at the lowest level, where +computer costs are considered, because it is easy to make quantitative +statements at this level. The running time to {\tt TANGLE} a \WEB\ file is +approximately the same as the time needed to compile the resulting +\PASCAL\ program; hence the extra preprocessing does not cost much. +Similarly, {\tt WEAVE} doesn't take long to produce a file for \TeX. +However, \TeX\ needs a comparatively large amount of time to typeset the +final document. For example, if we assume that each page requires four +seconds, it will take four minutes to produce a 60-page document. The +running time for {\tt WEAVE}-plus-\TeX\ is quite reasonable when you +consider that your program is effectively being +converted into a fairly substantial booklet; but the costs are sufficiently +large to discourage remaking and reprinting such a booklet more than once or +twice a day. When a new program is being developed, it is therefore customary +to work with hardcopy documentation that is slightly obsolete, and to read +the \WEB\ source file itself when up-to-date information is required; +the source file is sufficiently easy to read for such purposes. + +The costs of \WEB\ are more difficult to estimate at higher levels, but I have +found to my surprise that the total time of writing and debugging a \WEB\ +program is no greater than the total time of writing and debugging an +{\mc ALGOL} or {\mc PASCAL} program, even though my \WEB\ programs are +much better, and even though I am putting substantially more documentation +into the programs. Therefore I have lately been using \WEB\ for all of my +programming, even for one-off jobs that I write ``for my eyes only'' just +to explore occasional problems. The extra time I spend in preparing additional +commentary is regained because the debugging time is reduced. + +In retrospect, the fact that a ``literate'' program takes much less time to +debug is not surprising, because the \WEB\ language encourages a discipline +that I was previously unwilling to impose on myself. I had known for a long +time that the programs I construct for publication in a book, or the programs +that I construct in front of a class, have tended to be comparatively free +of errors, because I am forced to clarify my thoughts as I do the programming. +By contrast, when writing for myself alone, I have often taken shortcuts that +proved later to be dreadful mistakes. It's harder for me to fool myself in +such ways when I'm writing a \WEB\ program, because I'm in ``expository +mode'' (analogous to classroom lecturing) whenever a \WEB\ is being spun. +Ergo, less debugging time. + +Now that I am writing all my programs in \WEB, an unforeseen problem has, +however, arisen: I suddenly have a collection of programs that seem quite +beautiful in my own eyes, and I have a compelling urge to publish all of +them so that everybody can admire these works of art. A nice little 10-page +program can easily be written and debugged in an afternoon and evening; +if I keep accumulating such gems, I'll soon run out of storage space, +and my office will be encrusted with webs of my own making. There is no +telling what will happen if lots of other people catch \WEB\ fever and +start foisting their creations on each other. I can already envision the +appearance of a new journal, to be entitled {\sl Webs}, for the publication +of literate programs; I imagine that it will have a large backlog and +a large group of dedicated editors and referees. + +\beginsection M. RELATED WORK + +Nothing about \WEB\ is really new; I have simply combined a bunch of +ideas that have been in the air for a long time. I would like to +summarize in the next few paragraphs the things that had the greatest +influence on my thinking as I put those pieces together. + +George Forsythe wrote in 1966 that ``A useful algorithm is a substantial +contribution to knowledge. Its publication constitutes an important +piece of schol\-ar\-ship.''\ref\GEF{G. E. Forsythe, Algorithms for +scientific computation. {\sl Communications of the ACM\/ \bf9}, 255--256 +(1966).} His comments have always inspired me to strive for excellence +in programming, and they have played a major r\^^Dole in shaping my present +view that it is worthwhile to consider {\it every\/} program as a +work of literature. + +The design of \WEB\ was influenced primarily by the pioneering work +of Pierre-Arnoul de Marneffe,\ref\deM{P. A. de Marneffe, {\sl Holon +Programming}. Univ.~de Liege, Service D'Informatique (December, 1973).}$^,$% +\ref\deMR{P. A. de Marneffe and D. Ribbens, Holon Programming, in +A. G\"unther et al.\ (eds.), {\sl International Computing Symposium 1973\/}, +Amsterdam, North-Holland (1974).} whose research on what he called +``Holon Programming'' has not received the attention it deserves. His +work was, in turn, inspired by Arthur Koestler's excellent treatise +on the structure of complex systems and organisms;\ref\Koest{A. +Koestler, {\sl The Ghost in the Machine}. New York, Macmillan (1968).} +thus we have another connection between programming and literature. +A somewhat similar system was independently created by Edwin Towster.\ref\Tow% +{E. Towster, A convention for explicit declaration of environments +and top-down refinement of data. {\sl IEEE Transactions on Software +Engineering\/ \bf SE--5}, 374--386 (1979).} + +I owe a great debt to Edsger Dijkstra, Tony Hoare, Ole-Johan Dahl, and +Niklaus Wirth for opening my eyes to the importance of abstraction in the +reading and writing of programs, and to Peter Naur for stressing the +importance of a balance between formal and informal methods. + +Tony Hoare provided a special impetus for \WEB\ when he suggested in 1978 +that I should publish my program for \TeX. Since very few large-scale +software systems were available in the literature, he had been trying to +promote the publication of well-written programs. Hoare's suggestion was +actually rather terrifying to me, and I'm sure he knew that he was posing +quite a challenge. As a professor of computer science, I was quite +comfortable publishing papers about toy problems that could be polished up +nicely and presented in an elegant manner; but I had no idea how to take a +piece of real software, with all the compromises necessary to make it +useful to a large class of people on a wide variety of systems, and to open +it up to public scrutiny. How could a supposedly respectable academic, like +me, reveal the way he actually writes large programs? And could a large +program be made intelligible? My previous attempts along these +lines\ref\CF{D. E. Knuth, Computer-drawn flow charts. {\sl +Communications of the ACM\/ \bf 6}, 555--563 (1963).} were by now +hopelessly out of date. I decided that this would be a good time to try +out de Marneffe's ideas; furthermore, the \TeX\ system itself provided me +with new tools for printing and format control, so I suspected that it +would be possible to obtain state-of-the-art documentation by making +proper use of typography. + +It is interesting to reread some of the comments that Tony made ten years +ago in his keynote address to the first ACM symposium on Principles +of Programming Languages:\ref\Hoare{C. A. R. Hoare, {\sl Hints on +Programming Language Design}. Stanford Computer Science Report CS403 +(October 1973).} +\smallskip +{\narrower\noindent +Documentation must be regarded as an integral part of the process of +design and coding. A good programming language will encourage and +assist the programmer to write clear, self-documenting code, and even +perhaps to develop and display a pleasant style of writing. +\smallskip} +\noindent He foresaw many future trends, but not the impending improvements in +typesetting quality: +\smallskip +{\narrower\noindent +It is of course possible for a compiler or service program to expand the +abbreviations, fill in the defaults, and make explicit the assumptions. +But in practice, experience shows that it is very unlikely that the +output of a computer will ever be more readable than its input, except +in such trivial but important aspects as improved indentation. +\smallskip} + +Typographic formatting of computer programs has a long tradition, originating +with {\mc ALGOL} and its immediate precursors. I'm not sure who made the +first experiments, but I believe that the lion's share of the credit +for developing excellent programming-language typography belongs to two +people: Peter Naur, who edited the {\mc ALGOL~60} report\ref\Alg{P. Naur +(ed.)~et al., Report on the algorithmic language ALGOL 60. +{\sl Communications of the ACM\/ \bf3}, 299--314.} and gave special +care to its presentation; and Myrtle Kellington, who served for many years +as executive editor of ACM publications and set the standards that have +been adopted by other journals. The computing profession owes much to +these people, who made published programs so much more readable than they +would otherwise have been; the magnitude of their contribution can only +be appreciated by people who submit computer programs to journals +like {\sl Acta Arithmetica\/} whose editors are unfamiliar with computer +science. Bill McKeeman called attention to formatting issues when he +published Algorithm~268, ``{\mc ALGOL~60} reference language editor,'' +in 1965.\ref\McK{W. M. McKeeman, Algorithm 268. {\sl Communications +of the ACM\/ \bf8}, 667--668 (1965).} There has been a flowering of +such algorithms in recent years; the papers by Oppen\ref\DO{D. Oppen, +Prettyprinting. {\sl ACM Transactions on Programming Languages and +Systems\/ \bf2}, 465--483 (1980).} and by Rose and Welsh\ref\RW{G. A. +Rose and J. Welsh, Formatted programming languages. {\sl Software---% +Practice \char'46\ Experience\/ \bf11}, 651--669 (1981).} are particularly +noteworthy. + +I began to design \WEB\ in the spring of 1979, when I constructed a prototype +system that was called {\tt DOC}. Luis Trabb~Pardo helped me to develop +a suitable style of exposition at that time; then Ignacio Zabala~Salelles +gave a {\tt DOC} a thorough test when he prepared a full implementation +of \TeX\ in \PASCAL. Zabala's implementation was successfully transported +to many different computers,\ref\Z{I. Zabala and L. Trabb Pardo, +The status of the PASCAL implementation of \TeX. {\sl TUGboat\/ \bf1}, +16--17 (1980).}\silentref\ZZ{I. Zabala, \TeX-PASCAL and PASCAL compilers. +{\sl TUGboat\/ \bf2} (1), 11--12 (1981).}\silentref\ZZZ{I. Zabala, +Some feedback from PTEX installations. {\sl TUGboat\/ \bf2} (2), 16--19 +(1981).}$^-$\ref\ZZZZ{I. A. Zabala, How +portable is PASCAL? Draft of paper in preparation (1982).} +and this experience was of immense value to me when I cast \WEB\ into its +present form in 1981. Since then many significant improvements have been +suggested by my colleague David R. Fuchs, and I have also benefited from +the experiences of a large number of outstanding people who volunteered to +be guinea pigs for pre-released versions of \TeX. It's impossible for me +to name everyone who has helped, but I would like to give special thanks +to Arthur Samuel, Howard Trickey, Joe Weening, and Pierre MacKay for +important contributions. I'm fortunate indeed to share a working +environment with such stimulating people. + +When I originally designed the \WEB\ system, I spent about six +weeks preparing the files {\tt TANGLE.WEB} and {\tt WEAVE.WEB}, +during which time I was continually changing the language and +trying different styles of exposition. (The programs were neither +long nor complicated, but this was rather intensive work, so I +didn't get much else done during those six weeks. The first two +weeks were actually spent drafting the first ten per cent of what +is now {\tt TEX.WEB}.) Then I spent about six tedious hours with +a text editor, hand-simulating the behavior of {\tt TANGLE} on +{\tt TANGLE.WEB}, so that I had a program {\tt TANGLE.PAS} that +was ripe for debugging. At first I had to correct errors both in +{\tt TANGLE.WEB} and {\tt TANGLE.PAS}, but soon {\tt TANGLE} was +working well enough that I needed only {\tt TANGLE.WEB} as a +source file. Then {\tt WEAVE.WEB} could be tangled and debugged +too. The total time to create ``Version~0'' of the \WEB\ system, +including the language design and the time to debug the programs +and write a brief manual for users, was about eight weeks; then +enhancements were added at the rate of about one per month for +the next 18 months. As a result of this experience I think it's +reasonable to state that a {\tt WEB}-like system can be created +from scratch in a fairly short time, for some other pair of +languages besides \TeX\ and \PASCAL, by an expert system +programmer who is conversant with both languages. Indeed, I spoke +about \WEB\ on a recent visit to London and one of the people in +the audience decided to test this hypothesis; shortly afterwards I +received an elegant report from Harold Thimbleby, who had just constructed +an excellent system called {\tt Cweb}, based on Troff/Nroff and {\mc +C} instead of \TeX\ and \PASCAL.\ref\Thim{H. Thimbleby, {\sl Cweb}. +Preprint, University of York (August 1983).} + +\beginsection N. RETROSPECT AND PROSPECTS + +Enthusiastic reports about new computer languages, by the authors of those +languages, are commonplace. Hence I'm well aware of the fact that my own +experiences cannot be extrapolated too far. I also realize that, whenever I have +encountered a problem with \WEB, I've simply changed +the system; other users of \WEB\ cannot operate under the same ground rules. + +However, I believe that I have stumbled on a way of programming that produces +better programs that are more port\-able and more easily understood and +maintained; furthermore, the system seems to work with large programs as +well as with small ones. I'm pleased that my work on typography, which +began as an application of computers to another field, has come full circle +and become an application of typography to the heart of +computer science; I like to think of \WEB\ as a neat ``spinoff'' of my +research on \TeX. However, all of my experiences with this system have +been highly colored by my own tastes, and only time will tell if a large +number of other people will find \WEB\ to be equally attractive and useful. + +I made a conscious decision not to design a language that would be +suitable for everybody. My goal was to provide a tool for system +programmers, not for high school students or for hobbyists. I don't have +anything against high school students and hobbyists, but I don't believe +every computer language should attempt to offer all things to all people. +A user of \WEB\ needs to be good enough at computer science that he or she +is comfortable dealing with several languages simultaneously. Since +\WEB\ combines \TeX\ and \PASCAL\ with a few rules of its own, \WEB\ programs +can contain \WEB\ syntax errors, \TeX\ syntax errors, \PASCAL\ syntax errors, +and algorithmic errors; in practice, all four types of errors occur, and +a bit of sophistication is needed to sort out which is which. Computer +scientists tend to be better at such things than other people. I have found +that \WEB\ programs can be debugged rapidly in spite of the profusion +of languages, but I'm sure that many other intelligent people will find +such a task difficult. + +In other words, \WEB\ seems to be specifically for the peculiar breed of +people who are called computer scientists. And I'm pretty sure that there +are also a lot of computer scientists who will not enjoy using \WEB; some +of us are glad that traditional programming languages have comparatively +primitive capabilities for inserted comments, because such difficulties provide +a good excuse for not documenting programs well. Thus, \WEB\ may be only for the +subset of computer scientists who like to write and to explain what they +are doing. My hope is that the ability to make explanations more natural will +cause more programmers to discover the joys of literate programming, +because I believe it's quite a pleasure to combine verbal and mathematical +skills; but perhaps I'm hoping for too much. The fact that at least one +paper has been written that is a syntactically correct {\mc ALGOL 68} +program\ref\ft{C. H. Lindsey, ALGOL 68 with fewer tears. {\sl The +Computer Journal\/ \bf15}, 176--188 (1972).} encourages me to persevere +in my hopes for the future. Perhaps we will even one day find Pulitzer +prizes awarded to computer programs. + +And what about the future of \WEB? If the next year or so of trial use +shows that a lot of other people besides myself become ``hooked'' on this +method of programming, there will be many ways to incorporate the \WEB\ +philosophy into a really effective programming environment. For example, +it will be worthwhile to produce a unified system that does both +tangling and compiling, instead of using separate programs as in Figure~1; +and it will also be worthwhile to carry the unification one step further, +so that run-time debugging as well as syntactic debugging can be done +entirely in terms of the \WEB\ source language. Furthermore, a \WEB-like +system could be designed to incorporate additional modularization, +so that it would be easier to compile different parts of a program +independently. The new generation of graphic workstations makes it +desirable to display selected program sections on demand, by using \TeX\ +only on the sections that are of current interest, instead of producing +hardcopy for an entire document. And so on; a considerable amount of +additional research and development will be appropriate if the idea +of literate programming catches on. + +\bigskip\leftline{\bf Acknowledgements} +\smallskip +{\eightrm\baselineskip9pt +\noindent The preparation of this paper was supported in part by +the National Science Foundation under grants IST-8201926 and MCS-8300984, +and by the System Development Foundation. `\TeX' is a trademark of the +American Mathematical Society.\par} + +\enddoublecolumns % prepare for the references +\bigskip\bigskip +\hbox to\pagewidth{\hss\bf REFERENCES\hss\strut} +\CJrule width\pagewidth +\bigskip +\begindoublecolumns +\let\rm=\eightss \let\sl=\eightssi \let\bf=\eightssb \rm +\baselineskip=9pt +\tolerance=1000 +\references +\bigskip +\noindent +Received September 1983 +\enddoublecolumns +\kern6mm +\CJrule width\pagewidth +\bye |