Journo & Literate CoffeeScript

CoffeeScript 1.5.0 is out (with 1.5.1 impending), which means that the first release of Literate CoffeeScript is ready for public consumption.

Literate Programming is a venerable idea of Donald Knuth's — the idea that we should strive to write programs whose main purpose is the guided explanation to the reader of what the code is going to accomplish, and only incidentally and secondarily to explain to the machine how exactly to accomplish it.

Adventure A literate version of the classic "Adventure" game.

It may sound like a far-fetched idea at first, but it's also a fairly straightforward extrapolation from the history of programming languages. Code has always been a strange artifact, in that it's a single piece of text that's intended for both computers to read, and for people to read. If we truly only cared about efficiently programming a particular machine, and the human side had nothing to do with it, then we'd still be writing in machine code. The general evolution of programming languages away from the native machine language of the processor and towards natural languages and "pure" mathematical constructs is a shift away from addressing the machine head on, to a more comfortable middle ground, addressing both the machine and the human reader of the code.

Every time you choose to write in a "higher-level" or "more expressive" programming language at the expense of a few clock cycles, or choose to "drop down to the metal" to optimize, you're taking a position on that spectrum.

When you work in the spirit of Literate Programming, you take a very strong position on that spectrum indeed.


In the CoffeeScript implementation, we use Markdown as the documentation language. The usual prioritization of code over comments is inverted, and you write a valid Markdown document where the indented blocks of code happen to be a valid CoffeeScript program. Give this file a .litcoffee or a .coffee.md extension, and the CoffeeScript compiler will happily compile it to JavaScript for you — or run it directly.

In fact, the blog that you're reading this on happens to be one such Literate CoffeeScript program. I'm calling it Journo.

Journo The Journo source in a text editor

It's a basic blogging engine in 500 lines of code (including the documentation) that does a simple layout, index page and RSS feed, automatically keeps track of your posts for you in a manifest file, live previews via a local Node.js server, builds out a static version of the site, and then rsyncs it up to your web server with journo publish.

Working on it (on the plane, bus, backseat, quiet nights on shaky wifi) was a lot of fun. I started out with a document that was a simple bulleted list of the features I wanted it to have, took each feature one at a time and fleshed it out into a paragraph, and then picked out paragraphs to implement inline. A bit of rewriting, and when the document was done, the blog worked.

Nothing fancy, but I'm hoping that you find it clear and straightforward to read, and thereby perhaps easier to fork, or change to suit your own purposes.

Postscript

Frequently, when the topic of Literate Programming arises, someone will become apopleptic because this particular version doesn't encourage you to shuffle and reorder your source code into a different ordering for the reader than the one you pass to the compiler — as Knuth's original implementation did.

While reordering your source code was essential for older languages with strict compile-order-dependencies, in the modern world of dynamic languages, mutable classes and prototypes, dynamic linking and lazy loading, there's really no need for it. In fact, I think that the emphasis on shuffling your source is one of the reasons why Literate Programming found it so hard to gain a toehold in the first place.

I'd like to think that the balance of treating your code as a prose document first and foremost, with the implementation annotated among the paragraphs, serves as a happy medium where the file is easy to read, and the source is easy to follow (and debug!) as well.

Happy coding!