JAR's Scheme 48 Page

Below is some information on Scheme 48 offerred by Jonathan Rees. Any errors or omissions here are JAR's sole responsibility.

[23 April 2003] Changes and additions to this page are (usually) indicated with a bracketed date.

[20 August 2012] I made various updates throughout that I don't want to microannotate.

Early history: The toy

The Scheme 48 'project' began in August 1986. It was the result of a conversation between Richard and Jonathan immediately following the 1986 Lisp and Functional Programming Conference in which we considered the question "why do Lisp/Scheme implementations always become so complicated?".

Within 48 hours we had designed and implemented a working Scheme, including read, write, byte code compiler, byte code interpreter, garbage collector, and initialization logic.

Our hacking time together was limited since Richard had to return to New Haven. The name we chose was a nod to a 1982 film by Walter Hill, as well as a nod to another Scheme implementation known as Scheme 84.

The design, as it elaborated over the next couple of years, was in many ways a reaction to other systems of the 1980s that we had been using and/or working on, including

For the first year or so the sources lived on an ITS file server and saw some development by JAR. We developed under Common Lisp on the Symbolics 3600, as well as under Maclisp on the PDP-10, using various sets of macros that gave these Lisps a Scheme-like syntax. This was not 'incestuous' since the part of the system executed by the underlying Lisp (the virtual machine, or VM) was carefully written in such a way that it in principle it did not need a garbage collector, tail recursion, or other Lisp-specific apparatus; it was really a C or assembly-level program with Lisp syntax. Scheme 48's Lispy implementation language ('LIL' was the acronym used at MIT for this kind of thing in the 1970s) was later dubbed 'Pre-Scheme'.

In December 1987 we sent sources to Ozan Yigit, who was curious about it. This may have been the first 'release'. A mailing list was created at ai.ai.mit.edu for interested observers and advisors, which included Alan Bawden, John Wroclawski, Will Clinger, Norman Adams, and others.

In 1988-89 [?] Richard was working on Scheme 48 at Yale, using T as the bootstrap platform. He wrote the first compiler for Pre-Scheme, based on his dissertation work. Until this time, the virtual machine (eval + GC) ran only as a Lisp program (except see re Bob Brown, below). Since the compiler targeted C, we now had a way to create high-performance virtual machines for Scheme 48.

Later history: A useful thing

In summer 1990 JAR did some work on Scheme 48 at Xerox PARC. This is where the bignum code and generic arithmetic code started. JAR has a habit of writing code in such a way that he can can amuse himself and maybe learn something, and about 75% of the time these experiments have rather awful outcomes. (An example of this is the byte-code compiler's type system, which is useful but whose services and obligations are unclear.)

In 1991-92 JAR hacked intensively on Scheme 48 so that it could maintain a common code base with the Cornell Robotics and Vision Lab mobile robot system. This was the origin of the module system, which started as a way to decide which files to load. I had worked on module systems before without coming up with anything I liked, so rather than invent anything this time around I just tried to rationalize and Schemize Common Lisp's defpackage, with a dash of ML modules thrown in to make it interesting. The modules started out as lists of files, some of which belonged to the cross-compilation system, some to the interpreter, and some to the "run-time system" (auxiliary Scheme code such as read that is byte-compiled and subsequently byte-interpreted). I introduced new modules as necessary so as to carve the system into parts to be built into the mobile robot system, those to go into the teledebugging system, those to go into the full non-robot system, and those to go into the various overlaps of these destinations. For a long time it was enough for the module system to keep track of which files were to be loaded into the global namespace, but eventually the module system acquired a notion of interface and provided namespace separation.

For a testimonial on the module system, see this from Olin Shivers ("an incredibly cool mechanism").

[22 April 2003] I also had to introduce a system of integer identifiers to name various bits of debugging information, such as procedure names, correspondence between continuations and source code, etc. The robot knew the id's but not the textual information, which was kept on the other end of the 'tether' in the teledebugging system. This was the source of some bewildering and poorly documented complexity in the 'linker' (the thing that built heap images from scratch) and system bootstrap logic, but it was an essential tactic in keeping down memory use on the robot.

A milestone in the development of any programming language implementation that is expressed (at least in part) in the language itself is "self-hosting", i.e. building a runnable system using that implementation, rather than some other implementation of the same language. Scheme 48 was bootstrapped at various times from the Lisp Machine, T, Lucid Common Lisp, and Joel Bartlett's Scheme-to-C compiler, and by about 1990 was self-hosted. Often when a language implementation gets to the self-hosting stage the umbilical is cut and the ability to cross-build is lost. We resisted this temptation and made sure on an ongoing basis that a runnable image could always be constructed without relying on any running Scheme 48 implementation. Besides being a good general test of software hygiene, cross-building helps assure against (but doesn't guarantee?) the absence of backdoors of the kind described by Ken Thompson.

The earliest numbered version of Scheme 48 that I could find when I looked in late 2002 was version 0.20, made in May, 1993 (at Cornell). For version numbering I simply used the ITS convention of incrementing the version on every build, so the number rose quickly. The '0.' on the beginning was both a disclaimer (not yet version 1) and wishful thinking (maybe there will be a version 1).

Richard worked on Scheme 48 at NEC Research Institute for many years, and among innumerable other improvements, wrote a new thread system based on re-entrant schedulers that provides non-blocking I/O and an optimistic concurrency mechanism.

Richard also worked on native code compilers for Scheme 48.

[20 August 2012] Unfortunately my employment took me in other directions and I pretty much stopped work on it in the late 1990s, and Richard mostly stopped in the early 2000s. Mike Sperber started with our version from around 2000 and has been managing releases since then (starting with 1.1), continually improving it in many ways, with the help of various contributors. Version 1.8 of his series (Feb. 2008) features 64-bit support, among other things.

Scheme 48's place in the world

Scheme 48 has been aggressively un-marketed. Richard and I didn't really want to support a user community or lose the freedom to experiment, and Mike's series has continued to keep a low profile.

I heard that Scheme 48 had been considered as a foundation for Guile, the GNU scripting language, but was passed over due to licensing terms. (Did FSF contact us to see if we would change the license? No. We would have, and later did.) It was also considered for the Red Hat CD-ROM but was passed over (probably unnecessarily) for similar reasons. Eventually I think it made it into Debian distributions.

I suspect Scheme 48 had and has plenty of users. There were well over 500 downloads while I was making releases. I don't know what people do with it. Richard has the impression that most Scheme 48 users are scsh users (scsh, a Scheme shell for Unix, is based on Scheme 48).

Some notable consumers:

Publications: In 1994 Richard and I were invited to write a paper on Scheme 48's architecture for the journal Lisp and Symbolic Computation. I padded my dissertation with various things Scheme 48. There have been a few other publications related to Scheme 48, for which see Richard's home page and Jonathan's publications page.


Is it Scheme48, Scheme 48, or Scheme-48? I think we have used each of these at various times. At one point I preferred Scheme 48, by analogy with Algol 60 perhaps, and we tried to standardize to that. That was pre-web, and if I were to do it over I think I'd vote for Scheme48, which is easier for search engines to deal with.

Current status

[2 May 2011] The most recent Kelsey/Rees version of Scheme 48, variously called 0.59 and 1.0, was in 2000.

Richard and Jonathan both have jobs that don't involve further development of Scheme 48, so although they would like to, they aren't working on it much.

Mike Sperber and Martin Gasbichler at Universität Tübingen started doing their own releases with version 1.1 in 2004, and are putting them on s48.org.

[22 April 2003] Kolja Glogowski reports "that scheme48-0.57 is compilable on windows without modifications using the cygwin enviroment." [16 Dec 2003] Here are the sources for Northwestern's version of Scheme 48 for Windows. Mike Sperber is doing a fresh port that makes proper use of Scheme 48's event architecture.


Margaret Fleck produced a great manual that shamed Richard into finally writing an 'official' one.

Mike Sperber contributed a comprehensive C interface library, and many other features.

Brian Carlstrom maintained the mailing list for many years.

Paul Graham paid for DNS fees and infrastructure, and supported some work of JAR's on W7 (a secure capability-based virtual operating system built on Scheme 48) and other programming language related projects.

At various times MIT, Yale, Stanford, Xerox, Cornell, Northeastern University, NECI, and various granting agencies supported us while working on it.

Creative Commons License
JAR's Scheme 48 Page by Jonathan A Rees is licensed under a Creative Commons Attribution 3.0 Unported License.

JAR's home page