Knuth's concept of Literate Programming (LP) has been around since he published his paper in 1984. (Auspicious year!) If it is such a good idea, how come that after 28 years, there are so few examples of real-world use?
Short answer: Because most programmers are not writing code for use as examples in books or academic papers, nor do they seek the understanding of those illiterate in the (programming) language of choice the code is written in.
Longer answers (not necessarily in order of importance or frustration factor!):
- As a programmer, I am mentally incapable of--untangling, or is it unweaving? Maybe I'll stick with--rearranging the snippets of code littered (or maybe literated?) amongst large volumes of meaningless English prose.
It's meaningless because: the compiler won't compile it; the interpreter won't interpret it; and nothing on earth will test it!
- Neither the veracity of the claims it makes;
- Nor the correctness of the algorithms it describes;
- Nor the accuracy of correspondence between the prose and the code it purports to document.
- Instead of one level of maintenance, we have SIX! Six you say? Two surely? No! Six!!
- We have the English to maintain:
Is the phraseology clear? Are there no deceptive misspellings? No ambiguous punctuation?
- We have the algorithms and logic that the English describes to maintain.
Are the correct algorithms used? Is the logic, logical?
- We have the source code to maintain--in all the usual ways.
- We also have to ensure that the English description correctly describes the chosen algorithms.
- We have to ensure that the code actually implements the algorithms described, as described.
- And we have to make sure that the prose remains attached (physically adjacent to and above) the code it is describing.
And when it comes time to re-factor a portion of one of the code snippets, that we move the appropriate subsections of the the original description to where ever the refactoring takes that portion of code.
Six times as many ways to cock up, and none of the unnecessary five will likely ever have any automation tools that can be applied to them. At least, it's very unlikely in the working careers of anyone currently earning a living as a programmer.
- We have the English to maintain:
- It adds another layer between the product of the programmer: the source code; and the consumer of that product: the compiler or interpreter.
If you doubt that is a problem consider: Will compiler detected errors be reported in terms of their LP form line numbers or their post-processed form line numbers?
If you've used Inline::C (or any Inline::* language), they'll you'll undoubtedly be familiar with the game:
- Write code
- Attempt a run
- Compiler detects an error--lists the erroneous line number in yourfile_dead.xs(69)
- Navigate to ./_Inline/build/yourFile_dead_pl/yourFile_dead.pl But it's not there!
- Go back and add CLEAN_AFTER_BUILD => 0. Re-run.
- Compiler detects an error--lists the erroneous line number in yourfile_beef.xs(69)
- Navigate ./_Inline/build/yourFile_beef_pl/yourFile_beef.xs Load it into your editor.
- Examine line 69;, relate it to the error message; think for a bit; see what you think is the cause and correct it. Save file. Re-run.
- Compiler detects THE EXACT SAME error--lists the erroneous line number in yourfile_abcd.xs(69)
- Doh! Go back to the source (*.pl* file), work out which line in that file is the source for line 69 in the .xs file, Make the change (again!). Re-run.
- Compiler detects a different error--lists the erroneous line number in yourfile_a9c7.xs(73)
- Switch back to the editor, switch back to the .xs file. Line 73 *IS A BLANK LINE!*.
Doh! This ./_Inline/build/yourFile_dead_pl/yourFile_beef.xs Discard it!
- Navigate to ./_Inline/build/ ... which bloody suffix was the latest?
- Switch to other shell: Ah! A9c7
- Navigate to ./_Inline/build/yourFile_a9c7_pl/yourFile_a9c7.xs; load file to editor. What was that damn line number again?
- Examine line 73, relate it to the error message; think for a bit; see what you think is the cause and correct it. Save file. Re-run.
- Compiler detects THE EXACT SAME error--lists the erroneous line number in yourfile_abcd.xs(73)
- Pre-processors and textual substitutions are evil. (And I don't say that about many things!)
To see the point at its extreme consider the readmore in Re^3: WIN32-API Purgetory. Those 4000 lines of unintelligible code, manually extracted from amongst 26,000 lines filtered from a file containing 114,000 lines, are the result of applying a pre-processor to just 785 lines of source code input.
If you want easy maintenance?
Polluting the programmers primary workspace, in the ratio of 3 or 4 lines of noise to every line of productive code; and re-ordering the useful bits in some arbitrary fashion; using textual substitutions to further obfuscate things; and then adding another layer of indirection between what the programmer writes and the processor attempts to run --there are already too many levels--is not the right way to go about it.
- Application, program and library documentation has a different purpose and should be separate from source code.
Architects do not record their stress and strain calculations, or materials assessment tests on either their blue prints, or on the side of the building and bridges the design.
Or consider your lawyer presenting you with legal documents liberally strewn with footnotes and margin annotations of the form:
++Consider the term habeas corpus and the clarification of that term as laid out in Simpson v. Flanders (1999) and its the subsequent refinement in Itchy v. Scratchy (2001)
- Production source code in not the place to educate new programmers; nor document design decisions; nor record board meeting deliberations.
The programmers job is to write programs--not teach newbies how to program. There are schools and courses for that.
If you've any musical ability (I've none), then maybe this will convince you.
Imagine your average orchestra musician sitting down to a score like this:At the start of this piece the mood is melancholic. Don't be too s +trident. If you're playing the piano, press that "quiet pedal" a lot. If you're the tympanist, use your left hand to dampen the ketties +for the first few bars. Violins, blur the transitions between strings and 'bend' from note + to note. ===== ... ==*== ... ----*-... In these few bars, we start to get the sense of something awaking. + Piano, use the "soft pedal" less and less from beginning to the en +d of the passage, Toward the end, add the "loud pedal" on occasional sharps and flat +s. The kettles should be allowed to ring a little; and little more as + the passage progresses. Violins: Slowly clean up you transitions and blur them less and le +ss. = = - Bassists: This is your regular rhythm to be maintained throughout +the piece: = = - But there are two variations on this which you alternate between for the first two bars at the start of every other stanza--after t +he first four-- and for the last two bars of the alternate stanzas. = ... = ... = ... = ... - ... - ...
- Programmers write programs in programming languages, not just because it is easier to write
translators (compilers and interpreters) for them.
But also because their restricted syntax makes it easier to write correct, unambiguous and verifiable descriptions of algorithms. Neither English, nor any other natural language is a suitable substitute. And I'll stick my neck out and say: and never will be.
And the idea that writing code twice--once in the computer language; and a second time in an unverifiable, inherently ambiguous, infinitely variable of style--will some how render programs more reliable doesn't hold water.