Download the object code as classes.jar
and do
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.
Since
April 1998, development has been picked up by others, notably
Tim Hickey
at Brandeis and
Ken Anderson
at BBN. If you want the latest, full-featured version, look at:
There are a few things that are in Jscheme 1.4 that are not in R4RS
Scheme:
java jscheme.Schemefiles
Any arguments on
the command line are interpreted as files to be loaded. For
example, you can test the system for compliance with the Scheme
standard with: java jscheme.Scheme r4rstest.scm
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.
(error x...)
Prints an error mentioning all
the arguments, and then throws out to the read-eval-print loop.
(time-call proc k) (time-call
proc)
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)
This
macro evaluates expk times (or once if k is not
given). It then returns the same statistics as time-call.
Example:
> (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.
(class string)
returns the Java class named
by the string. For example, (class "java.awt.Frame").
(new class)
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.
For example:
(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
scope.
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
(lambda (x)
(and (number? x)
(= x (round x))
(< (- x 1) x (+ x 1))))
To Do
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.
A GUI.
An applet version available over the web.
Add BigInteger or BigDecimal numbers. Or maybe a new
LongRational class.
Make everything 10 to 50 times faster (I hope) by pre-treating expressions
before evaluating.
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
The Revised4 Report on the Algorithmic Language
Scheme (postscript
or HTML). The
version of the standard that Jscheme is currently based on. See also
the r4rstest.scm
compliance test.
The Revised5 Report on the Algorithmic Language
Scheme (postscript
or HTML). The
very latest version of the standard, also compatible with the IEEE standard.
IEEE Standard 1178-1990. IEEE Standard for the Scheme Programming Language
(Not available online. You have to buy it from IEEE.)
Scheme Compilation Books
Christian Quenniac's Lisp in Small
Pieces is a good reference for interpreting and compiling Lisp.
Friedman, Wand and Haynes's Essentials of
Programming Languages is a good introduction to programming
language design and implementation. It also uses Scheme.
Scheme Implementations (In Java)
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.
Quenniac's PS3I
is a persistent server-side Scheme interpreter written in Java.
General Scheme Resources
Aubrey Jaffrey's SLIB is a
comprehensive Scheme source code library.
The table below gives code size measurements in bytes and lines,
for object and source code. "KB" means 1000 bytes, not 1024. "Source"
includes some Scheme code as well as the Java code.
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
StringBuffers,
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.