A blog post about my recent work, which is what I demoed a while ago in an online meetup: blog.khinsen.net/posts/2025/06/25/hyperdoc.html
Oh this is awesome! Common Lisp is definitely on my very short list of suitable platforms for Convivial/Freewheeling computation. So I'm very interested in contributing.
I'm still working my way through the demos. Some initial impressions:
- Are you really running Common Lisp within the browser?!
- Alt-click is kinda unreliable. I tried alt-clicking on the close/reload/maximize buttons on the top-right, and it was unclear what I was getting back in response. On one occasion I got a blank frame with just an outline and nothing else. So far I haven't gotten it to show me anything useful.
- In the
Navigating a HyperDoc
pane, in theComputed text
section, it would be good to show an example of computed text with the dashed underlines. Maybe have7*6
compute to 42. - Meta lesson from the previous bullet: would it be possible to create publicly accessible hyperlinks to specific sections in a HyperDoc? š
Continuing to read..
- The way the horizontal scrollbar highlights background when I hover on it, I worry that there are 2 nested scrollbars one on top of another. Maybe just stop highlighting the background on hover?
- In
Influenza epidemics in France
, could you link to a definition for relative incidence ? Should it go to en.wikipedia.org/wiki/Relative_risk?
- In the table
ari-incidence-france
, I wish each checkbox/line would have a consistent color.
Common Lisp (SBCL) is running on the server. The communication with the browser happens via a WebSocket, managed by CLOG. But Common Lisp in the browser is coming. Daniel KochmaÅski (current ECL maintainer) has a proof-of-concept of a compiler to WASM, and just announced that he received a grant to continue working on it.
Alt-click works on all items in the title bar of a pane, and on the tabs representing the views. It does weird things indeed on the close button - I hadn't imagined somewhat might try š
Computed text: good point. You can see one at hyperdoc.khinsen.net/377F4-influenza-epidemics-in-france, at the end of the first paragraph.
URLs for pages/sections: as my example above shows, there are persistent links to sections. In the "URL" view. I could do those for pages as well.
I don't see the scrollbar issue (Firefox). And I fear that my CSS competence is insufficient to deal with such issues!
Relative incidence is just cases divided by population. Not sure there is something obvious to link to. I should ideally just compute it, the code would then be the unambiguous definition.
Enabling or disabling the playground is done via a flag when starting the server (development=nil).
Colors: good point. codeberg.org/khinsen/ari-incidence-france/issues/1
Ah cool. How can I find the URL for a section?
In the URL tab on class hyperdoc. Assuming that's what you mean by section.
Enabling or disabling the playground is done via a flag when starting the server (development=nil).
I imagine there are security issues involved? Maybe just tweak the message to say it will be available when running locally, and point readers at the repo.
Yes, it's disabled because otherwise people could run arbitrary Lisp code on the server. The message should indeed be more explicit!
š Explain disabled playground
- Mention security
- Point to the repo for local installation
I'm definitely not seeing any change when I alt-click on tabs representing views.. oh, I just reloaded the tab and now I see it working. So there's some flakiness somewhere. At some point in a session it very commonly stops working for me, to the extent that it seemed totally broken across multiple sessions until now. I'm using Waterfox, and will also test on Firefox in a bit.
How can I install HyperDoc's dependencies locally? I don't really understand asdf or QuickLisp yet, so the command in the Readme doesn't work for me.
Common Lisp software installation comes in three layers:
- The language itself has (load ...) for reading in a file. And nothing else (well, there's defsystem, but it's basically useless today).
- ASDF is the de-facto code management layer that nowadays is shipped with all CL implementations. Its unit of software is the 'system', defined in terms of code files and dependencies in a system definition file (extension .asd). That's how all Lisp code is packaged nowadays. If you manage to track down the repositories of all dependencies, recursively, you can clone them into $HOME/common-lisp and you are ready to go:
(require 'asdf)
and then(asdf:load-system "hyperdoc-demo")
. - Software catalogs and package managers take care of downloading dependencies from the right places. There are the system-wide ones (Debian, Guix, ...), but also a few Lisp-specific ones, out of which Quicklisp is by far the most popular. It's very easy to install, and mostly just works. But its default software catalog is updated only about twice per year. If you want bleeding-edge code (such as mine), you have to add a second catalog, Ultralisp, which is easy to add as well. If you have those two, and followed their advice of activating Quicklisp on startup (in $HOME/.sbclrc for SBCL), then
(ql:quickload "hyperdoc-demo")
will download and load everything you need.
I provide instructions for Quicklisp (which I use on my old Mac) and for Guix (which I used under Linux). I have tested my system with SBCL and ECL, the two Lisp implementations well supported by Guix.
Philosophical note: Common Lisp is fortunate to have ASDF separate from Quicklisp and other package managers. The fusion of their Python or JS equivalents makes it a pain to assemble polyglot software. With Lisp, any package manager can delegate the Lisp-specific stuff to ASDF. And Lisp developers don't have to know about anything else than ASDF.
I provide instructions for Quicklisp
Oh did I miss this? I don't see where you do.
(I do have QuickLisp setup. I can be dangerous with it even though I have no understanding of it.)
codeberg.org/khinsen/hyperdoc-demo
The HyperDoc demo and all its dependencies are on Ultralisp. If you use Quicklisp and Ultralisp, you can run the Web server using:
sbcl --disable-debugger \
--eval '(require :asdf)' \
--eval '(asdf:load-system "hyperdoc-demo")' \
--eval '(hyperdoc-demo:serve :port 9000)' \
--eval '(sleep most-positive-fixnum)'
I just updated the server with various improvements as discussed above!
Hoo-boy, I just noticed installing Ultralisp requires glorified curl |sh
on a http rather than https URL.. I might wait a bit to try running this.. definitely on my radar, though.
It's not quite curl | sh
. The closest moral equivalent I see is using npm
. Installing Ultralisp is low-risk, but there's a subsequent risk in installing packages from Ultralisp, which is a mostly uncurated software catalog. http
then seems like a minor additional risk. My understanding is that it's due to Quicklisp not handling encryption for some reason. So if it's http
you are worrying about, you shouldn't be using Quicklisp at all. Which is one reason why my main Lisp development environment is managed by Guix.
Ugh, you're right. I see now that the transcripts on the Quicklisp frontpage involve getting from http
URLs. This is going to require rethinking my Quicklisp setup..
(I personally don't see much difference between curl |sh
and the npm eco-system. But they do seem to benefit some from at least pervasively using https. I like the idea of supporting http
and tend to be on balance slightly against https. But there have been too many cases of intermediaries inserting data into payloads to justify downloading code over http
, IMO.
Minor story: back when I launched lines.love in Mar 2022, akkartik.name used to be served over just http
. So I hosted my download link at tilde.club. When I realized certbot was now push-button easy, I added https
as well, but made it a point to keep http
working. But now I notice akkartik.name redirects to akkartik.name š¬ Gotta debug that some time..)
Zooming out on my security stance:
- I care very much about minimizing dependencies and knowing where I get them from. I mistrust overly large and popular vendors, as well as tiny and anonymous vendors. I want to know more about who the people are behind a program or library.
- Given that concern about people, I also care about making sure random large/popular or tiny/anonymous folks can't get between me and the people I choose to enter into relationships with.
I am ambiguous about http
vs. https
as well. Bot-in-the-middle attacks are real enough to worry about downloading code via http
. But https
implies serious dependencies on Big Tech. Let's Encrypt is what makes https
accessible to most of us small players. But it's backed by the big ones, and they can pull out any time once http
support in browsers and other tools starts to disappear or become unusable.
Guix (and others) provide a better solution to code trust: it's not based on the source, but on cryptographic verification of the code itself. Nothing fancier than checksums, but applied systematically across the whole dependency chain, including build scripts.
Of course, no technology is more secure than the people who run it. It is conceivable that someone puts malware into popular code (the xz
story), and that can happen at all levels, including Guix' build scripts. Perhaps the best protection of the Common Lisp ecosystem is its small size: it's simply not attractive as a medium to spread malware.