Literate Programming in Spacemacs with Racket

Introduction

So maybe one day out of the blue you thought to yourself, “I’d really like to work through SICP or The Little Schemer. And wouldn’t it be neat if I could do it all in the ultra-powerful Org-mode so I can take detailed notes about what I’ve learned along the way. Hmmm… isn’t that called literate programming? I wonder what that’s all about…”

Hey, me too!

And then some time passed and now through the magic of search engines or social media marketing or whatever, you ended up on this page. Isn’t this exciting!

Literate programming is a game-changer. Through Emacs you can access the shell and various programming languages like Python, Elixir, and Racket all in your org buffer. You can interact between them and even pass data between cells of different languages. It opens up a whole new world of prose-first, highly interactive coding.

Okay, you’re already sold. Let’s get started.

Install Racket & the Racket Layer for Spacemacs

First, visit http://spacemacs.org/layers/+lang/racket/README.html for more info on the Spacemacs layer for Racket.

According to that documentation, we need DrRacket installed, so I chose the full Racket install package in Arch. This will give you Racket, the raco cli tool, and the DrRacket IDE.

sudo pacman -S racket

For other operating systems, see: https://www.racket-lang.org/download/

Next, add the Racket layer to your Spacemacs config. Open the Spacemacs configuration editor with SPC f e d. Then add racket to your list of configuration-layers.

dotspacemacs-configuration-layers
'(
  ; ... other layers
  racket
)

Install the layer with SPC f e R.

Add ob-racket.el for Org-mode support

To evaluate Racket code in Org-mode source blocks, we need to install the appropriate Babel plugin for Racket. While some layers include an Babel plugin, unfortunately the Racket layer doesn’t specify one. We’ll have to add it manually.

There are a number of options available on GitHub. I chose https://github.com/DEADB17/ob-racket.

Install this file by adding it to the additional-packages section in your Spacemacs config:

dotspacemacs-additional-packages '(
  ; ...
  (ob-racket :location
            (recipe :fetcher github :repo "DEADB17/ob-racket"))
)

And the documentation for ob-racket.el shows that we need to add the following lines to user-config.

(defun dotspacemacs/user-config ()
  ; ...
  (use-package ob-racket
    :after org
    :pin manual
    :config
    (append '((racket . t) (scribble . t)) org-babel-load-languages))
)

Save your changes, then refresh your configuration with SPC f e R to install ob-racket.el.

The thrilling finale in which we evaluate Racket code

Add a code source block to an Org-mode file. Type <s TAB to expand a blank source block snippet.

Write some code and then, while in the source block, evaluate it with C-c C-c. You’ll see the results appear in a section below the code.

#+BEGIN_SRC racket
# lang racket

(* (+ 2
      (* 4 6))
   (+ 3 5 7))

#+END_SRC
#+RESULTS:
: 390

Note the #lang racket in that source block. Racket won’t evaluate the source successfully without it — you’ll get an error saying Babel expects a string blah blah. Turns out you’ll have to add it to the top of your code every time. So that’s a minor annoyance.

We can work around it by adding some flags to the header of the source block like this:

#+BEGIN_SRC racket :lang racket/base :results output
(define (square x) (* x x))

(define (sum-of-squares x y)
  (+ (square x) (square y)))

(sum-of-squares 3 4)
#+END_SRC

#+RESULTS:
: 25

It works. Amazing. Just add your typical text notes, tables and other Org-mode elements alongside your Racket code. Now we’re both literate programmers!

Here’s a screenshot of the output:

One last thing. The above steps will work for many other languages. Just add the appropriate Spacemacs language layer and optionally find and install the necessary Babel plugin and you’re ready to go.

Liked it? Take a second to support Eric on Patreon!
Default image
Eric

Leave a Reply