|
Literate programming is the writing of computer programs primarily for human beings to read, similar to a work of literature; hence the name "literate programming." This contrasts with the traditional view that a programmer's primary creation is source code to be read by a computer. Documentation and source code are written into one source file. Both the complete source code and its documentation can be extracted from this file with specific utilities. The information is written and presented in a reading order suitable for human consumption with detailed explanations. The code is automatically rearranged for ordinary processing by other computer tools, such as compilers or interpreters.
History and current implementations The first published literate programming environment was WEB, introduced by Donald Knuth in 1981 for his TeX typesetting system; it uses Pascal as its underlying programming language and The complete commented Outlining Outlining editors are sometimes seen as providing a variant of the original concept of literate programming as used by Knuth. In particular, Leo combines outlining with interfaces to noweb and CWEB processors. Embedded documentation There are also less powerful systems to integrate documentation and code than literate programming; examples are pod for perl, doc++ for C, C++ and Java, javadoc for Java, and Doxygen for many languages. These however do not quite follow the literate programming philosophy since they typically just produce documentation about the program, such as specifications of functions and parameters, and not documentation of the program source code itself. They also do not allow rearrangement of presentation order, which is critical to the effectiveness of literate programming. See documentation generator. Haskell is a modern language that makes use of a limited form of literate programming: this semi-literate style does not allow code re-ordering or multiple expansion of definitions but lets the programmer intersperse documentation and code freely. It is the fact that documentation can be written freely whereas code must be marked in a special way (see the example below) that makes the difference between semi-literate programming and excessive documenting, where the documentation is embedded into the code as comments. Doctests Similarly to source code, testing code that exercises an API can be embedded within human-readable documentation, along with the expected output of the calls. A test runner extracts and executes the code and verifies its output against the expected output. This idea originated from the Python programming language. An implementation is provided by the Python standard library's doctest module. Program This section contains a literate program, which can be run using the example literate interpreter in the Interpreter section For this particular interpreter, all the program code must be written on lines starting with a dash. Everything else is ignored by the interpreter. This does not support some important aspects of advanced literate programming like code rearrangements or multiple expansion and so should only be called basic literate programming or "semi-literate" literate programming.
Interpreter The following simple interpreter program is written using BASIC. When compiled using the QuickBASIC compiler it is a straightforward interpreter but when run on the QBASIC interpreter, it is an example of an interpreted interpreter.
LINE INPUT SplitFirst KeyWord$, FileInput$ SELECT CASE KeyWord$ CASE "-" SplitFirst KeyWord$, FileInput$ GOSUB InterpretKeyword END SELECT LOOP CLOSE InterpretKeyword: SELECT CASE UCASE$(KeyWord$) CASE "STORE" GOSUB AssignToValue CASE "ADD" GOSUB AddToValue CASE "MULTIPLYBY" GOSUB MultiplyWithValue CASE "PRINT" GOSUB PutOutput CASE "CLEARSCREEN" GOSUB ClearScreen CASE "NEWLINE" CASE ELSE PRINT "I don't know what "; KeyWord$; " "; FileInput$; " means." END SELECT RETURN AssignToValue: GOSUB GetArg LET Value$ = Arg$ RETURN AddToValue: GOSUB GetArg LET Value$ = LTRIM$(STR$(VAL(Value$) + VAL(Arg$))) RETURN MultiplyWithValue: GOSUB GetArg LET Value$ = LTRIM$(STR$(VAL(Value$) GetArg: Split KeyWord$, FileInput$ SELECT CASE UCASE$(KeyWord$) CASE "INPUT" GOSUB GetInput LET Arg$ = UserInput$ CASE "VALUE" LET Arg$ = Value$ CASE "TEXT" LET Arg$ = FileInput$ CASE ELSE LET Arg$ = KeyWord$ + " " + FileInput$ END SELECT RETURN GetInput: LINE INPUT "", UserInput$ RETURN PutOutput: GOSUB GetArg PRINT Arg$; " "; RETURN ClearScreen: CLS RETURN NewLine: RETURN SUB SplitFirst (aFirst AS STRING, aRest AS STRING) DIM J AS INTEGER LET J = INSTR(aRest + " ", " ") LET aFirst = LTRIM$(LEFT$(aRest, J - 1)) LET aRest = LTRIM$(MID$(aRest, J)) END SUB To try with the above program, save the interpreter as INTERP.BAS and then save the program section as TESTPROG.TXT in the same folder. Run INTERP.BAS with either QBASIC or QuickBASIC. See also | ||||||||
|
| |||||||||
![]() |
|
| |