summaryrefslogtreecommitdiff
path: root/web/literateprog/web.tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/literateprog/web.tex
Initial commit
Diffstat (limited to 'web/literateprog/web.tex')
-rw-r--r--web/literateprog/web.tex1477
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