This chapter discusses Leo's relationship with traditional literate programming.
Contents
The following paragraphs discuss the main benefits of traditional literate programming. Note: none of these benefits depends on printed output.
Design and coding happen at the highest possible level. The names of sections are constrained only by one's design skill, not by any rules of language. You say what you mean, and that becomes both the design and the code. You never have to simulate a concept because concepts become section names.
The visual weight of code is separate from its actual length. The visual weight of a section is simply the length and complexity of the section name, regardless of how complex the actual definition of the section is. The results of this separation are spectacular. No longer is one reluctant to do extensive error handling (or any other kind of minutia) for fear that it would obscure the essence of the program. Donald Knuth stresses this aspect of literate programming and I fully agree.
Sections show relations between snippets of code. Sections can show and enforce relationships between apparently unrelated pieces of code. Comments, macros or functions are other ways to indicate such relationships, but often sections are ideal. Indeed, a natural progression is to create sections as a matter of course. I typically convert a section to a function only when it becomes apparent that a function's greater generality outweighs the inconvenience of having to declare and define the function.
Complex section names invite improvements. A section name is complex when it implies unwholesome dependencies between the caller (user) of the section and the section itself. Such section names tend to be conspicuous, so that the programmer is lead to revise both the section name and its purpose. Many times my attention has been drawn to a poorly conceived section because I didn't like what its name implied. I have always been able to revise the code to improve the design, either by splitting a section into parts or be simplifying its relation to colleagues.
Sections create a place for extensive comments. One of the most surprising thing about literate programming is how severely traditional programming tends to limit comments. In a conventional program the formatting of code must indicate structure, and comments obscure that formatting. Sections in literate programming provide a place for lengthy comments that do not clutter the code at the place the section is referenced.
Section names eliminate mundane comments. The section name often says it all. The reference to the section says everything that the user needs to know, and the section name at the point of definition also eliminates the need for many comments.
Sections create comments automatically. A typical @root node starts out with something like:
<< includes for class x >> << private data for class x >> << private prototypes for class x >> << functions of class x >>
In the derived file there is a comment that looks like this:
/// << includes for class x >>
It would be silly to write this comment by hand, though often programmers do just that in order to have a place holder for a mark in the source file. With literate programming the situation is different: the comment indicates that the code came from a particular section; that is, the comment servers a real purpose.
Literate programming clarifies the shape of code. These last several paragraphs have discussed comments in detail because the net effect of "putting comments where they belong" is that comments don't clutter the code. Section references hide irrelevant detail, so larger-scale patterns within functions (or declarations) become more apparent. Often just recasting code into web format has created Aha's about my own code, with no special attention to recoding or redesign! Recasting a function as a web raises the real and apparent level of abstraction.
I spend less time formatting code. Formatting no longer has to indicate overall design; sections do that. I am less obsessive about formatting code; it simply doesn't matter much whether different sections are formatted consistently because the format of one section has no effect on the look of other sections. Also, I don't worry about most line breaks within documentation parts, or about adding comment delimiters.
Literate programming creates a new design dimension. Sections add a new dimension to the design and coding process. Choices about what sections do, what they are named, what order they appear in, are choices in a design space different from "normal" programming. This an abstract concept, to be sure. However, the previous paragraphs are really a manifestation of working in this new design space.
Outlines add something brand new to traditional literate programming, namely an explicit mechanism for expressing structure at any level of detail, from largest overall view to smallest detail. The following paragraphs elaborate on this theme.
Outlines add context. There are too many sections in conventional literate programming. It becomes difficult to understand the relationships between sections. Using an outline to express a literate programming instantly solves this problem. The programmer is always aware of how sections are related.
Outlines provide scope for commands. Outlines provide a convenient way of expressing the intended scope of commands. For example, the Tangle command operates only on the presently selected tree. The Extract Section command creates a new section as the last child of the present node.
Clones create different views and focus attention. Clones can create different views of the outline. An outline can contain many such views. Clones & views discusses the implications of clones in detail.
Outlines increase flexibility. Organizer nodes do not affect derived files in any way, but organizer nodes often convey the most information about the structure and design of a large system. Decoupling structure from content in this way is precisely what is needed for flexibility: one can reorganize at will without worrying about changing the meaning of the code.
Outlines express hierarchy directly. Hierarchy is often implicit in programming: for example, the grouping of functions into files, or the organization of a single file as a set of functions, etc. An outline directly expresses hierarchy. Many of Leo's commands operate on the presently selected node. It is natural to apply operations on selected node of the outline.
reStructuredText is much easier to use than CWEB markup. Leo's rst3 plugin makes it easy to use reStructuredText (rST) instead of CWEB markup. For most purposes, rST suffices, and rST is much easier to use and less intrusive than CWEB.
Outlines create new design dimensions. There are many ways to express a program as a Leo outline. Such choices are important. They add clarity to the entire program. These are different kind of choices. They simply can not be expressed at all in other editors. In other words, such choices exist in a new design space.
Leo improves tangling and adds untangling. Tangling and untangling are fundamental operations of literate programming. Leo tangles and untangles files derived from @file trees automatically. This is an important convenience.
Leo changes the theory and practice of literate programming as follows:
Leo reduces the need for comments. In particular, bridge or transition phrases are almost always unnecessary in a Leo outline. One never needs to say something like, "having just finished with topic x, we turn now to topic y." Leo's outlines tend to be far less chatty than flat literate programs.
Leo reduces the need for printed listings. Experience with the Weave command shows that an outline can easily become unintelligible when printed, no matter how "beautiful" the typeset printout is. No printed listing can be as clear as Leo's outline view.
Leo reduces the need for indices and tables of contents. You could say the entire outline is a table of contents. Moreover, sections must always be defined in a descendant of the node containing the section reference, so there is very little need for an index.
Leo shows that outline structure is more powerful than narrative. Indeed, narrative style creates severe maintenance problems. The narrative is soon forgotten, and when that happens it becomes difficult to find anything. The few times I have tried narrative organization I soon regretted it: things just weren't where I expected them to be.
Leo shows that traditional literate programming encourages a too creative approach to programming. A dictionary is a better model for programs than a novel. Leo's outlines provide a more regular organization, while providing space for the most lengthy discussions when those discussions are required.