New Interactive Tutorial Format for Racket Libraries

Hi folks,
I don't know about you, but I learn best in an interactive setting, where I'm engaged with the material I'm trying to learn, where there is a tight feedback loop that allows me to see right away whether my understanding is correct or not. I know I'm not alone in this, as decades of Lisp culture around REPL-driven development attests.

So why is it that the default way to learn a new library in Racket is to read the docs? Most docs aren't set up to help you learn in an interactive way, and, indeed, documentation is written to serve many different goals, only one of which is to help you learn. The others include: to serve as a reference, to serve as a troubleshooting resource, to provide a view into the implementation, the mechanisms, and design choices, and more. Good documentation must achieve all of these goals, and teaching poor you how to use the dang thing isn't always the top priority.

Well, no more! With the specific goal of learning in mind, Qi now offers an interactive tutorial optimized for the Racket ecosystem. This was made possible by the help of Stephen De Gabrielle @spdegabrielle , who first suggested distributing a runnable Qi application, and Laurent Orseau @Laurent.O who added really nifty support for this format for DrRacket users. This post is not about Qi, but rather about the format of this tutorial, which may be of interest as it could be broadly adopted.

What is the tutorial format?

The tutorial is just a Racket source tree - a collection of Racket modules. It is structured as a series of comments containing the tutorial material, interspersed with code illustrating the ideas described (i.e. similar to many of the language-oriented tutorials on "Learn X in Y minutes" (https://learnxinyminutes.com/)).

As Matthew Butterick says, "the book is a program." And with this style of tutorial, to turn it around, "the program is a book."

Since these are just normal Racket modules, they allow and encourage you to try out variations inline and experiment on your own before proceeding -- add marginalia, if you will. And just like in any textbook, there are also included exercises to practice your skills and develop fluency.

How is it distributed?

It is distributed using the handy from-template package by Philip Dumaresq.

To get started on a tutorial, you simply need to install from-template:

raco pkg install from-template

And then run this at the command line to install a tutorial:

raco new <tutorial-name>

And you now have a working Racket source tree containing a runnable tutorial for the new library (e.g. for Qi's tutorial, use raco new qi-tutorial). Btw, note that from-template is intended to distribute templates for Racket projects in general (like Python's Cookiecutter), and is not specific to tutorials.

Another way to distribute the tutorial could be something like Denxi, but I haven't had a chance to explore this option yet.

Where could this style of tutorial be used?

For any library that has a nontrivial learning component. I can think of a few libraries off the top of my head that could benefit from a tutorial in this format:

  1. megaparsack (whose tutorial is already excellent, and could easily be provided in interactive format virtually as is)
  2. rosette (I think a lot of people (myself included) are curious about Rosette, and an interactive tutorial would certainly lower the barrier to entry and open the door to learning what it can do)
  3. brag

... not to mention many specialized areas of Racket more generally, such as syntax-parse.

How can I adopt this for my library?

  1. Write the tutorial and put it in a dedicated repo e.g. mylibrary-tutorial (you could just start with a placeholder first and improve the tutorial over time until it's ready to be announced)
  2. Host it on e.g. GitHub or GitLab
  3. Register your tutorial for distribution by submitting a PR to add it on the racket-templates repo
  4. Link to it in your docs (example)
  5. Announce it

Why should libraries consider providing an interactive tutorial? Aren't the docs enough?

With documentation, I think it's fine to say the same thing many times in many different ways (e.g. this great talk by Jacob Kaplan-Moss, one of the authors of the widely admired Django docs (and Django :wink: )).

In that spirit, for library authors, a tutorial isn't an alternative but a complement to other docs. It tells your users that you care about their time and want to make sure they don't waste it reading things they won't understand until they are ready.

For users, just consider this: in order to learn a new library, would you rather (A) read or (B) play?

I rest my case :slight_smile:

Finally,

Are you sure this format is the right one?

No. Ideas welcome!

-Sid

9 Likes

Hi Sid! Very nice idea! I find the approach very interesting and I'll consider preparing something similar for one of my packages/libraries.

I also thought of the Emacs tutorial while reading your post.

2 Likes

Oh that's true @scolobb , the Emacs tutorial (and the Vim tutorial vimtutor for that matter) are good examples of this as well!

I'll just peep my new package that is highly specific to vim+tmux+demos at the command-line, since it's in a similar vein: tmux-vim-demo

Basically the demo script turns into a program that opens vim (editing the demo script) on one side and a shell on the other, with keybindings to send lines under the cursor to the other side. You can launch and interact with arbitrary programs this way (including vim), as long as having a trailing newline sent is ok (not usually true in vim…). Very useful for demoing CLI apps, working at a REPL, etc., without making typos/worse at presentation time. Plus, since you're in such control of what lines get sent when, you can jump around live with less fear.

2 Likes

That sounds very relevant, and looks like it could be used to run the tutorial in Vim (unless there's already another way to send expressions interactively?). For demos, I actually hacked together a one-off script to do this in Emacs for my talk at RacketCon - this on the other hand sounds like it has the potential to be a good, standard way to do it.

I did run into some issues, though - It wasn't completely obvious how to set it up from the reading the docs, so I'm documenting my steps in case you'd want to include something like it (and in case I did something wrong!):

Install vim-tbone:

cd ~/.vim/bundle
git clone git://github.com/tpope/vim-tbone.git

Install tmux-vim-demo

raco pkg install tmux-vim-demo

Create a script called demo.rkt:

#lang tmux-vim-demo

(+ 1 2)
(displayln "hello!")

And finally,

$ racket demo.rkt
system*/exit-code: contract violation
  expected: path-string?
  given: #f
  context...:
   /Applications/Racket-Latest/collects/racket/system.rkt:174:0: do-system*/exit-code
   /Users/siddhartha/Library/Racket/8.3/pkgs/tmux-vim-demo/main.rkt:33:24
   body of "/Users/siddhartha/work/lisp/racket/sandbox/tmux-vim-demo/demo.rkt"

Any ideas?

1 Like

Nuts. It looks like you did everything right, so I'll need to check this out. Thanks for letting me know.

One thing to note is that, assuming you want to send those S-expressions to the Racket REPL, I would include a line with racket first to start that REPL, since you get a generic shell when the demo stats.

@countvajhula Does (find-executable-path "tmux") work? You need to have tmux installed.

I should push an update to check the result of find-executable-path, though.

@benknoble that was it! Installing tmux fixed it :+1:

This is fantastic, I've added tmux-vim-demo to the README as the recommended way to run the tutorial for Vim users, and I'll be adding it to the Qi docs soon as well.

One thing though, at the moment, this would require users to modify an existing Racket module that they intend to run interactively (such as the Qi tutorial) by adding a header specific to tmux-vim-demo. Even using the (require tmux-vim-demo) approach with a separate runner script, they'd still need to manually enter the word racket into the Racket buffer in order to enter the Racket REPL before continuing with the rest of the module. Do you think it would be possible to support some form of "pre" step where we can run some commands before running the demo in filename (via run-demo)? I think this would make it more seamless for Vim users and could also make this package compelling to use with any existing Racket module without modification, and not only demos or tutorials. There's no rush to figure this out at all by the way, and I'm sure Advent of Code problems are keeping you occupied atm, so I'll just create an issue on the tmux-vim-demo repo and we could continue the discussion there!

1 Like