4 ms·
I've been deeply fascinated by the idea of literate programming, but every time I dive into the programs themselves, they leave something to be desired. First,
by cxr 6y ago
I've been deeply fascinated by the idea of literate programming, but every time I dive into the programs themselves, they leave something to be desired.
First, though, I glossed over the PBRT shoutout and thought the Academy Award mention was about lkesteloot's team's award, until I scanned back and saw that it was about PBRT. To qualify that, here's one of lkesteloot's comments from his Oscars page on his personal site:
> Our renderer and lighting tool were individually good, but lots of renderers and lighting tools are good. What made ours unusual (and it’s unusual in this respect to this day) is that they were designed and built at the same time, with each other in mind. <https://www.teamten.com/lawrence/oscar/ https://www.teamten.com/lawrence/oscar/>
It might not be obvious, but this really touches on a part of the philosophy underpinning literate programming. If you look at any of the recent discussions about Knuth being "framed" in relation to the seminal Programming Pearls guest column, one of the recurring themes is programs as monoliths. In a really spectacular post "An app can be a home-cooked meal" <https://www.robinsloan.com/notes/home-cooked-app/ https://www.robinsloan.com/notes/home-cooked-app/>, the author explains his own work and likens it to Shirky's description of "situated software". Shirky writes, "Situated software isn't a technological strategy so much as an attitude about closeness of fit between software and its group of users" <https://web.archive.org/web/20040411202042/http://www.shirky.com/writings/situated_software.html https://web.archive.org/web/20040411202042/http://www.shirky...>. This obviously sounds a lot like PDI's renderer and very much characterizes Knuth's monoliths. I always liked this quote from literateprogramming.com:
> The fundamental logic of the WEB system encourages "top-down" programming and "structured" design. Quoting from Kernighan and Plauger, 'Top-down design and successive refinement attack a programming task by specifying it in the most general terms, then expanding these into more and more specific and detailed actions, until the whole program is complete. [...] The WEB system encourages you to work top-down by giving you the ability to break up your code into independent segments (called "sections").
Coincidentally, in addition to lkesteloot's Oscar comments, he's got a pretty great essay called "Write code top-down" which really delves into the matter <https://www.teamten.com/lawrence/programming/write-code-top-down.html https://www.teamten.com/lawrence/programming/write-code-top-...>. Opinionated and well worth the read.
As for this interview, PBRT, and Knuth's flavor of literate programming: the PBRT book is available for free online <http://www.pbr-book.org/3ed-2018/Introduction/Literate_Programming.html http://www.pbr-book.org/3ed-2018/Introduction/Literate_Progr...>, and the intro starts out with a section on literate programming and the WEB/noweb family in particular <http://www.pbr-book.org/3ed-2018/Introduction/Literate_Programming.html http://www.pbr-book.org/3ed-2018/Introduction/Literate_Progr...>. This, I think, is already adequate to highlight some of the issues with the WEB/noweb implementation of literate programming. It's still too mired by constraints of C (or maybe since the language isn't technically C, and Knuth is also known for literate programming with Pascal, we should chalk it up to something akin to Sapir–Whorf?). akkartik has a good essay on the matter of Knuth's programs <http://akkartik.name/post/literate-programming http://akkartik.name/post/literate-programming>. akkartik:
> just about every literate program out there begins with cruft like this: `// Some #includes` or: `-- Don't mind these imports.` I used to think people just didn't understand Knuth's vision. But then I went and looked at his literate programs.
Indeed, I've also looked at Knuth's programs and felt a similar twinge. There's the seminal column, available from literateprogramming.com and linked from akkartik's post. Having tried to read it, a big issue there is that the problem just isn't very interesting in my opinion, at least on practical grounds. I've mentioned before that I think a literate programming advocate and true believer would do well to do something like publish a piece that focuses on implementing support for DEFLATE and the ZIP file format, which strikes me as a much stronger hook than a program to "print the k most common words in the file in decreasing frequency" or "Dijkstra's program [that] prints a table of the first thou-sand prime numbers". No matter, though. There are "real" programs published by practitioners of the style, right? How about Knuth's rendition of Colossal Cave Adventure? <http://literateprogramming.com/adventure.pdf http://literateprogramming.com/adventure.pdf> Once again, we're really running into sharp edges of C that WEB—or at least this particular text—doesn't do a good job of softening up, for the reasons akkartik rightly points out. Just look at the second page and right away with `main` we've got unexplained a priori structure, including stuff like local variables j, k, and p.
Other programs I've looked into are lcc, and the glimpses I've gotten of Inform 7. On my first encounter with the former, I was motivated to jot down in my notes a proposed law that said, roughly, a poor/failed attempt to write a literate program will produce a piece of text that's harder to understand than if it had just been written "straight".
Still, I'm hopeful that there's something there to be found in literate programming. In fact, I'm pretty sure there is something there. I wrote a recent comment soliciting info and critiques/criticism about literate programming for pedagogy <https://news.ycombinator.com/item?id=25498685 https://news.ycombinator.com/item?id=25498685>.
And it's funny that you mention TypeScript. As I said, I think part of the inadequancy of CWEB comes down to C. C is fundamentally opposed to one's attempts to practice top-down programming—one of the first things that "every" programmer learned, back when "every programmer" meant programmers who learn C, is that when you read a C program, you're supposed to start at the bottom and kind-of-sort-of read it backwards. Although I suppose there's an argument to be made that were it not the case for C (or Pascal) inflicting this upon you, then Knuth may never have been sufficiently motivated to undertake his literate programming crusade in the first place.
I've had niggling thoughts that a language like JS with support for forward declarations in the form of function hoisting and its dynamism at runtime, including allowance for function redefinition (or at least if not JS, then something with similar properties) would be a more perfect match for the top-down style associated with literate programming. TypeScript, though, might be a little too strict that causes it to suffer for similar reasons as C. Also the fact that JS's roots lie in a (much maligned) system for conveying documents (as opposed to an application platform) makes the fit even better. It's just that nobody seems to be noticing this feature-not-a-bug, because they've been focused on trying to recreate mobile app conventions in the browser. And I've actually sat down to experiment and play around with the affordances that could prove TBL's Web (as opposed to Knuth's WEB) a more attractive substrate for a literate programming system. More recently, I've gotten more serious about actually testing the limits of the medium while thinking of things to put together that are meant to be consumed by other people as pieces of written works to be read from top to bottom in Knuthian style, but it comes down to a matter of having enough time.
A final note is that in Bob Nystrom's post on 'Crafting "Crafting Interpreters"' <http://journal.stuffwithstuff.com/2020/04/05/crafting-crafting-interpreters/ http://journal.stuffwithstuff.com/2020/04/05/crafting-crafti...>, he more or less lays out the case for a literate programming system to help with actual book authoring.
I hope that if you or anyone else decides to take an interest and try hashing something out that you're successful.
- taeric 6y agoI think this shares some of my early gripes with literate programming. That it seemed very hung on c or pascal. It eventually stuck me as being part of the point. It is not supposed to be a new language. It is supposed to be how you would explain an implementation to another person. That is, it is not an attempt to hide the structure of a program. Such that having an intro section that basically lays out the structure of the language being used for the computer is sort of on key. Seeing a literate implementation of "wc" is not supposed to give more clarity to how "wc" exists as an algorithm, per se. It is supposed to give a view of an implementation that is readable to a person, though. And, often, the idioms of how you read a whole program should guide how you write the literate one. This is probably not line by line. But it probably is guided by your existing knowledge of the implementation language.
- cxr 6y agoThanks for the thoughtful response, but I don't think I can say I agree with your conclusion. One example I cited was Knuth's Adventure. Even knowing C well enough, I'm not struck by how Knuth's presentation makes it easier to understand in the way he desires. Knuth very much seems to advocate for programs that can be read cover-to-cover (e.g. while, say, sitting in your favorite chair). I think the failure in his literate programs come down to the blindspots he's developed working on his own programs, from having focused so much on the trees in their respective forests. You can see something similar at play in Graham Nelson's struggles to make Inform 7 appropriately "literate", which funnily enough exhibits the opposite of expectations of familiarity with the original implementation language. <http://inform7.com/talks/2020/06/07/narrascope-ii.html http://inform7.com/talks/2020/06/07/narrascope-ii.html> Have a look at this slide in particular: <http://inform7.com/assets/images/NS2/slide036.jpg http://inform7.com/assets/images/NS2/slide036.jpg> Here's an excerpt: "Once The Historian is done, the instructions are passed to Instruction::read, which parses them more fully (see below) and returns an intest_instructions object". It goes on in that style. This is reminiscent of every bad attempt I saw during Java's heyday to ensure that a given codebase was 100% commented. People just end up writing "documentation" that consists of low-level repetition of what the code is doing, but without explaining why it's doing those things, and that why is key. It's the only real reason to be concerned with making sure things are documented. The code itself explains the how (in excruciating detail, even), the selection of identifier names more or less does the job of explaining the what. It's the role of the comments to explain the why, because (crucially) there is otherwise no substitute for this reified in the code itself, unlike the case with identifier names and procedural control flow. From my original notes upon seeing that slide from the Inform 7 talk: > You don't need to tell us that the instructions are passed to `Instructions::read`, which returns an `intest_instructions` object, because if that's true, then we can already see that. This type of documentation contributes nothing except to people who are new to the programming language you're using, but that's not your audience. > The ONLY way to document a program is to understand that almost everything you write needs to be an answer to the question, "What problem existed that led to this piece of code being created?" Your job is not to describe your solution. We already have your solution and can read through it. Your job is to describe the problem(s) for which your program is a solution. Namely, a problem is defined by its constraints. Detail all of those constraints [before ever thinking of telling us how it is you've decided to work with them]. What do you think of akkartik's take on the imperative to effectively communicate whole-program concerns at the global level? <http://akkartik.name/about http://akkartik.name/about>