Skip to content

Instantly share code, notes, and snippets.

@tmtvl
Last active November 22, 2020 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmtvl/67da1611b1ab27eeb6402c1363d6013b to your computer and use it in GitHub Desktop.
Save tmtvl/67da1611b1ab27eeb6402c1363d6013b to your computer and use it in GitHub Desktop.
Article for Raku Advent 2020

Literate Programming with Raku

Different programming language communities have differing cultures. Some are more pragmatic, others more idealistic. Some place great emphasis on having code be thoroughly readable and understandable for anyone who joins an existing project, and some prefer writing out clear and in-depth documentation.

Raku, inheriting one of the best parts of Perl, has a community that writes great documentation.

What is Literate Programming?

Literate Programming is an alternate take on documentation. Instead of having the code be the central element and writing documentation around it, in Literate Programming we write a document that contains the essential parts of our program. In this way we integrate the code into our natural language in such a manner that the idea underlying the design is clear. In this way we also naturally start thinking explicitly about the operations our programs need to perform to fulfill the task we are setting out to undertake.

Literate programming is not to be confused with documentation generation; it's not merely having a program that is well-documented with documentation lavishly surrounding the code and embedded into it, rather it's having a document about the program in which the program itself is embedded. As Lewis Carroll had the Mad Hatter say in Alice in Wonderland:

You might just as well say that "I see what I eat" is the same thing as "I eat what I see"!

What is Org-mode?

Org-mode is a text-editing mode in the Emacs Lisp interpreter (which could arguably be called a text editor). When Org-mode is enabled one can edit text using a specific type of markup, called Org. Similar to Markdown, it supports basic text features like headers, basic text properties like bold or italic text, embedded hyperlinks, embedded code blocks, and so on.

However, due to the versatility of the Emacs platform Org-mode has been extended with a facility termed "Babel", which allows authors to execute blocks of source code. Various languages are supported out of the box; unfortunately Raku, still being a rather young language despite being quite old, is not among those. To remedy that, I wrote a package called ob-raku that extends the Babel facilities to add Raku to the supported languages.

Using Ob-Raku

To use ob-raku in Emacs one will need to download the package (simple clone it from GitHub or download one of the release tarballs) and add it to their Emacs load path. This can either be done using the environment variable:

export EMACSLOADPATH="/path/to/ob-raku:$EMACSLOADPATH"

Or you can change the path in your configuration file (probably ~/.emacs or ~/.emacs.d/init.el):

(add-to-list 'load-path "/path/to/ob-raku")

After adding the path you can add Raku to the list of languages that Babel can use like this:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((c . t)
   (emacs-lisp . t)
   ; ...
   (raku . t)))

With Raku added to the list, you can create a Raku code block like this:

#+BEGIN_SRC raku
"!dlroW ,olleH".flip
#+END_SRC

You can evaluate the block by putting the cursor in or at the end of it and either using the menu bar, or typing C-c C-c (which is the Emacs notation for Ctrl+c Ctrl+c). The result of the evaluation will be added after the code block.

Linking blocks

Unfortunately, the lack of session support for ob-raku means that functions declared in one block aren't usable in other blocks. That said, the results of evaluating a block can be used as arguments to another block, to chain them together. So when editing a .org file we can write the following:

Let's make a list in Raku:

#+NAME: nested-list
#+BEGIN_SRC raku
my @a = (("A", "B"), ("C", "D"))
#+END_SRC

We can also include results from other languages:

#+NAME: elisp-list
#+BEGIN_SRC emacs-lisp :results vector
'(1 2)
#+END_SRC

And now we'll use the lists we just defined:

#+NAME: crosser
#+HEADER: :var a=nested-list() b=elisp-list()
#+BEGIN_SRC raku
my @crossed = @a X @b
#+END_SRC

When you evaluate the crosser block Babel will evaluate the nested-list and elisp-list block, which both return lists, and assign them to the @a and @b variables. The resulting crossed list will be returned underneath the crosser block.

Editor's notes

This post was drafted at the end of February 2020, before Daniel Sockwell wrote his excellent article on Literate Programming with Pod6. This post won't be mentioning using Pod6 to do Literate Programming, but talk about an Emacs package I wrote to use Raku in Emacs Org-mode.

Raku REPL interaction in Emacs was still underway when this article was written, thanks to Matías Linares it has since solidified.

Conclusion and thanks

While the functionality of ob-raku is still limited, anyone who already uses it to write documents can now implement Raku code and thereby show reproducible data expressed in our lovely versatile language, and once session support lands Org-mode's built in tangling facilities should bring true Literate Programming to the community.

Creating ob-raku would not have been possible without the work put in to raku-mode, so I would like to thank everyone involved in the project for their hard work. While our community is small, having people with passion work on improving the tools we use on a daily base makes our work much more enjoyable and thereby helps us keep going to make our little slice of heaven the best it can be.

@JJ
Copy link

JJ commented Nov 21, 2020

OK, here are a few edits:

  • Add links to a definition of literate programming. Don't be shy on linking even basic concepts.
  • It would probably be best to put the Editor's note at the end
  • "generation, it's" → "generation; it's"
  • Add comma after "similar to markdown"
  • "box, unfortunately" → ; also
  • I wrote a package → add "ob-raku" and link to it (some instructions on how to install it would also be nice)

(The initial version of my "Learning perl 6 was written in org-mode, BTW. I eventually ported it to markdown for easier edition)

  • Matías probably has a tilde on the í
  • comma after unfortunately
  • I miss a bit of explanation of the Linking blocks part. I have no idea how Lisp works.

When you're done with that, I'll move it to Wordpress and assign authorship to you. Thanks!

@tmtvl
Copy link
Author

tmtvl commented Nov 21, 2020

I've updated the article, if there's anything else you would like to see changed feel free to mention it.

@JJ
Copy link

JJ commented Nov 22, 2020

Thanks!

@JJ
Copy link

JJ commented Nov 22, 2020

Scheduled for Dec 1st, and authorship is yours, so you can touch it up before that date. Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment