1. 27
  1. 5

    This looks very nice. I’ve known about Knuth’s cweb and friends for a long time, but this looks like a very user-friendly tool. I’d like to try it on a small project at work soon, see if our eternal documentation problems can be made a little better.

    1. 1

      I wrote a dumb and simple script today that makes illiterate programs, if you want I can put it up on GitHub. All it does is convert commented source to a markdown, but it is easier than adopting one of these literate tools.

      1. 2

        Yeah sure, I can write 80% of one of these in Perl in an hour, but then I’ll give up before I get to the integration with error reporting from the compiler which is the key to getting anyone else to go along with this.

        1. 1

          yeah I have no idea how to get a team to adopt better documentation, let alone literate programming :/

    2. 2

      I’ve used it before. It’s nice. I keep running into the odd issue with it, though, and since I don’t know D it’s hard for me to volunteer to fix it.

      1. 2

        What issues have you run into? I hadn’t written any D before this morning, but something woke me up very early and I filed a couple of PRs to the project to fix some minor things that I’d seen. Maybe we can figure this out together.

        1. 1

          See eg https://github.com/zyedidia/Literate/issues/29 where Markdown footnotes don’t quite work. There was something else but I don’t remember it being as frustrating.

        2. 1

          How would you compare to alternatives like noweb or emacs Babel for org-mode? I used Babel but hated the emacs dependency

          1. 2

            I also used to use emacs org-mode. It’s notably less featureful than org-mode but is more useful right off the bat. And it produces nicely styled pages, too. The nice thing about emacs org-mode is that you can edit in any editor you want and only use emacs to compile your literate code.

            Literate is much much much easier to use than noweb, and does not require using LaTeX (which IIRC noweb does).

        3. 2

          I am strongly reminded of lit.sh, a similar any-language approach to literate programming, which itself is based on mdlp.awk. The main difference is one of size.

          1. 2

            I vastly prefer the approach that lit.sh takes over this. Literate seems to allow for defining arbitrary blocks wherever and then providing primitives for assembling, which is flexible but seems confusing. A more inline, top down approach, like that from org-mode + Babel or lit.sh is the sweet spot for me.

            1. 3

              This is a feature from the original literate programming tools. Wikipedia has a section on it: https://en.wikipedia.org/wiki/Literate_programming#Order_of_human_logic,_not_that_of_the_compiler. In fact, I think it was the whole point of literate programming. The examples Knuth gave were great, he’d say something like:

              The outline of the program is
              
              --- somefile
              @{Includes}
              @{Globals}
              @{Functions}
              @{Main}
              ---
              
              The first part of the problem we will tackle is outputting the information to the screen.
              We would first need to include stdio.h in order to write to the screen
              
              --- Includes+=
              #include <stdio.h>
              ---
              
              We should also name the variables we will store the word count in
              
              --- Globals+=
              int bytes = 0;
              int words = 0;
              int lines = 0;
              ---
              
              Then finally we can write a function to print these out
              
              --- Functions+=
              void print_result() {
                …
              }
              

              Nothing too exciting so far right? But the real kicker comes when we start working on the input to the system, we can go back and append to includes/globals/functions. We’re not using the order the program is written, but the order we want to explain the problem in. This is more relevant in certain runtimes/languages (I’m thinking of (require 'foo) in Cljs or #include in C).

              1. 2

                I hadn’t thought about it that way, but I can see how it makes sense. You can tell the story in a way that is separated from the flow of code. I guess I’d argue that in most languages you can (at least) forward declare functions that aren’t being used yet, making it possible to do this by writing a program from top to bottom in whatever order the functions make sense to introduce them in?

                It seems like a mental gymnastics exercise to piece together the program in the Literate source form, otherwise…? Perhaps I should give it a try and see. I could be completely wrong.

                1. 2

                  The given point seems worth taking on its face. I used lit.sh to design literate code support for Monte, and looking at the module where I first developed and used that support, the very beginning of the file starts with a bunch of imports and then an apology for the fact that some things will be declared in an awkward order because we don’t detangle.

            2. 2

              I used literate programming for a while, and literate was the best tool I could find which would allow me to swap blocks around. My use case was for my init.vim/vimrc. In particular I wanted to place my plugins close to the configuration for them, but sometimes that configuration would need specific ordering:

              • Plugin definitions need to go between plug#start() and plug#end()
              • Configuration might go in vimrc (if it’s g:foo)
              • Some calls or maps might go in an ftplugin file

              Scattering it around made it much more difficult to track down everything I’d changed about a particular plugin to remove or fix something.

              The massive downside was that the compilation process didn’t feel very portable. I just had this binary blob I lumped around and couldn’t get to work in unusual environments. I eventually solved this problem by using Dein’s hook functions to put configuration in callback functions, but my ftplugins are a mess again.