Download the object code as classes.jar
java jscheme.Scheme scheme-files...
Jscheme is my implementation of Scheme in Java. This page presents Jscheme
version 1.4, the last version that I released (in April 1998). If you want
a mercilessly small, easily modifiable version, this is it.
April 1998, development has been picked up by others, notably
at Brandeis and
at BBN. If you want the latest, full-featured version, look at:
This syntax is defined
so that (define
name (macro (args) body)) is just like Common Lisp's (defmacro
name (args) body). I realize I should add a mode where this syntax
is not used.
Prints an error mentioning all
the arguments, and then throws out to the read-eval-print loop.
(time-call proc k) (time-call
calls the procedure proc and
returns a three-element list of the result, the number of milliseconds
and the number of bytes consumed by the call. If k is given, it
calls k times, and returns the result from the last call.
(time exp k) (time exp)
macro evaluates expk times (or once if k is not
given). It then returns the same statistics as time-call.
> (time (zero? 0) 1000)
(#t (53 msec) (48000 bytes))
(exit k) (exit)
exits from Java, returning
k as the exit code if it is present and is a number,
otherwise the exit code is 0.
returns the Java class named
by the string. For example, (class "java.awt.Frame").
creates a new instance of the
Java class. For example, (new (class "java.awt.Frame"))
(method m o cs...)
returns a procedure that
invokes a Java method m on an object o. The cs are
names of classes (or class objects) for the arguments of the method.
(define show (method "show" "java.awt.Frame"))
(show (new "java.awt.Frame"))
Continuations can only be used as escape procedures; that is they
can only be called while the surrounding try/catch is still in
read does not handle all the lexical syntax for numbers
(e.g. #e123#.#F-3+#b1/#d4#i). The language standard says "any
particular implementation may support only some" of the written
notations for numbers, so this does not appear to be a violation.
The distinction between exact and inexact is not right. I represent
all numbers as double precision floating point, and define both
exact? and integer? as
(and (number? x)
(= x (round x))
(< (- x 1) x (+ x 1))))
There are a few things on my "to do" list:
Better support for errors: catch some errors that kill the system,
allow user to interrupt and get into a break loop or back to top level,
provide for recovery from errors.
Better integration with Java methods.
Better way to use multi-threading.
Functions for web access.
An applet version available over the web.
Add BigInteger or BigDecimal numbers. Or maybe a new
Make everything 10 to 50 times faster (I hope) by pre-treating expressions
R5RS support. This requires hygienic macros (which
Dorai already did for me) and fifteen new procedures: two-argument
eval, scheme-report-environment, null-environment,
interaction-environment, numerator, denominator, rationalize,
string-copy, string-fill!, vector-fill!, port?, char-ready?, values,
call-with-values, and dynamic-wind. For dynamic-wind,
I will probably have the same limitations as with call/cc.
I believe it is legal to do
Michael Travers' Skij (Scheme in Java) is similar enough to Jscheme that if Skij had existed, I wouldn't have done Jscheme. Some minor differences: Skij strings are immutable, in violation of Rn Scheme, but in alignment with Java; more of Skij is written in Scheme.
Per Bothner's Kawa is a
near-complete R5RS Scheme in Java, with many
Common-Lisp-like extensions, that compiles to Java byte codes.
The resulting code is much faster than Jscheme, but Kawa is 605KB
(23K lines) of source code, and 540KB of object code (loaded on
demand); more than 10 times more than Jscheme on both counts.
is a persistent server-side Scheme interpreter written in Java.
General Scheme Resources
Aubrey Jaffrey's SLIB is a
comprehensive Scheme source code library.
Moved the remaining Scheme code to SchemePrimitives.java. Its
still the same Scheme code, but now it is read from a Java string rather than
from a file. This way everything is in Java, and we don't have to
worry about opening files at start-up time, and with potential
file-reading security restrictions with applets. For editing
convenience, the following two perl commands convert from normal text
to this Java quoted String format and back again (note they need to
first convert between " and \"):
perl -pe 's/"/\\"/g; s/([^\s])/"\1/ and s/\s*$/\\n" +\n/'
perl -pe 's/\\"/"/g; s/"// and s/\\n" \+//'
Version 1.3: Released April 15, 1998
Put everything in a package.
Moved everything but some macros from primitives.scm to
Primitive.java. Makes for faster runtime and loading time.
Only increased the number of lines of code by about 50.
Changed the stringify interface to use a single StringBuffer.
Before, if you had a ten element list, stringify created ten
and then merged them into an eleventh. Now its all done in one StringBuffer.
As a matter of fact, it might have been better for Java to provide this kind of
interface for its toString method.
Version 1.2: Released April 10, 1998
Converted from PrintStream to PrintWriter. No deprecation warnings now.
Made the error routine throw a RuntimeException.
Improved javadoc comments.
Version 1.1: Released March 30, 1998.
Made (1 .2) read as (1 0.2), not (1 . 2).
Added warning messages that #x and the like are not implemented.
Added cddddr and the other 3- and 4- c[ad]r procedures.