So many package managers

Written by Göran Weinholt on 2018-02-25

In a previous article, I wrote about Akku.scm, a package manager for Scheme. It is far from being the first package manager or even the first for Scheme. There have been at least a dozen failed attempts at getting something going.

Dorodango is another package manager aimed at R6RS. It works more like a system package manager (apt, dpkg) in some sense. You point it at a repository and it can then install packages for you. It is not project-oriented and does not help you with locking specific dependencies for your project. It was later forked as Guildhall for GNU Guile. That one has also stopped moving (perhaps they moved to Guix).

Another package manager is Raven, which is targeted at Chez Scheme. It wants to be installed by root into /usr/local but can then be used by unprivileged users. It’s quite new and doesn’t really have a lot of features yet. It works and it can download some packages. You can have a look at the code yourself, it’s quite small.

There are a bunch of defunct package managers: Alex Shinn’s Common-Scheme, Will Donnelly’s UnCommon Lisp (UCL), Marc Feeley’s Scheme Now! (the first Snow), Aaron Hsu’s DeSCoT, Higepon Taro Minowa’s spon and Manuel Serrano’s ScmPkg.

Centrifugal vs. centripetal

The ScmPkg paper (Serrano and Galleiso, 2007) is interesting reading. They make the distinction between centrifugal and centripetal approaches. The centrifugal approach is to attract users to the language implementation by having a lot of libraries, so that a community forms around it, which then contributes more libraries to it. The centripetal approach is to create some common framework that, if used, lets unmodified Scheme code run in multiple implementations.

There are successful centrifugal projects. SchemeSpheres is, according to their site, like the batteries (as in batteries included) for the Gambit Scheme compiler. The site is a bit wonky at the moment and the blog was last updated in 2014, but they have around 150 libraries. Even more successful, I would say, is Eggs for Felix Winkelmann’s Chicken Scheme. But the grand winner in this contest must be Racket Packages for Racket. You know you have a winner on your hand when they have four different sets of bindings for ØMQ. (Snide remarks aside, they are very popular).

There are centripetal approaches alive today, but they are not anywhere near as popular as Eggs or Racket Packages. Snow is the successor to the old Snow (Scheme Now). It’s alive and in use by some Scheme implementers and a handful of other people. Eerily similar to Snow is Snow2 by Seth Alves. Some or all of this is the basis for a rather flawed R7RS package repository format.

My pointy analysis (the rant)

The centrifugal approaches are excellent for the implementations that they target. Chicken and Racket are themselves excellent implementations and better off for their package repositories. But it’s not directly useful to Scheme as such. The packages are not portable between implementations. Not what I’m looking for.

Centripetal is no good either. In my opinion, Snow suffers from the same problems as other centripetal approaches. The packages in ScmPkg used .spi files that defined an interface and did include of some code from regular naked .scm files. Snow does the same but calls those files .sld and relies heavily on cond-expand. Same kind of animal. So every library is divided in two files and on top of that it’s #ifdef Hell all over again.

I don’t think Akku falls directly into either centrifugal or centripetal, and neither should it. Something else is going on. As I wrote in Akku’s README: It grabs hold of code and vigorously shakes it until it behaves properly.

Akku is built on the solid ground of R6RS Scheme. This provides a target that is well-specified and stable. Sure, some things are not specified, such as how libraries are stored in the file system, but that is where Akku comes in and bridges the gap between the code and the implementation. I think this is a better approach than, let’s say, smugly not providing a REPL just because R6RS didn’t specify the procedures necessary for it. (Such an implementation should, to be consistent with its ideals, not permit loading libraries from the file system either).

R6RS does not have cond-expand. Instead there is a de facto standard of loading .<impl>.sls before .sls that all R6RS implementations support, as well as Akku. This works better than the cond-expand forms which tend to show up in every little library file. (Can you find the typo’d SRFI number hidden in one of the cond-expands in Chibi Scheme?). The .<impl>.sls approach, on the other hand, results in a few libraries where all the non-portable stuff goes. You end up building reusable abstractions instead of clutter. That is just better.

And R6RS already supports libraries. ScmPkg had to target any number of module systems. I think it is rather telling that the centripetal approaches tend to expect implementers to write their own clients for the package system.

Minor R7RS rant

I can not write my software with R7RS as the target language. My critiques are too numerous and I don’t even know how my name got into the standard.

However the library system in R7RS is quite alright, basically being a downgraded copy of that in R6RS, and a future Akku version is likely to support R7RS/Snow packages. They would be installed both for use directly in R7RS implementations and lightly converted for use in R6RS implementations. Going in the other direction is not possible in the general case (see the botched attempts at porting Industria to R7RS).

To me R7RS-large looks like the centrifugal approach, except applied directly to the language standard. Most of what it attempts to accomplish has been possible with R6RS all along. More progress would have been made in this if Scheme standardization had not been turned into an “Us vs. Them” game. It disillusioned and demotivated many schemers.

Besides, implementers who want access to many libraries can add R6RS support, which I think will be less effort than adding R7RS-large.


I stand in front of you. I’ll take the force of the blow. Protection.

– Massive Attack – Protection

Am I the only one to see that the Snow repository format uses unpadded RSA signatures, to be verified by keys sent next to the signatures over plain http? As we say in Sweden: va?

The other package managers listed are not any more serious about security either, but at least they don’t pretend to be either. Racket is again the best of the bunch.

I’m taking Akku’s security seriously. That includes using standard cryptographic protocols and algorithms, independently verifiable signatures on the package index, message digests on all downloaded code, no arbitrary code execution on installation and manual reviews before code even shows up in the official index.

We are all friends here but let’s not kid ourselves, the Internet is a wild place, and let’s have some standards.