Java [JavaSpec] has primitive types (such as
32-bit int
) as well reference types.
If a variable has a reference
type, it means that it can contain references (essentially pointers)
to objects of a class, or it can contain references to objects of
classes that “extend” (inherit from) the named class.
The inheritance
graph is “rooted” (like Smalltalk and unlike C++);
this means that all classes inherit from a distinguished class
java.lang.Object
(or just
Object
for short).
Standard Scheme [R5RS]
has a fixed set of types, with no way of creating new types. It has
run-time typing, which means that types are not declared, and a
variable can contain values of different types at different times. The
most natural type of a Java variable that can contain any Scheme value
is therefore Object
, and all Scheme values must be
implemented using some class that inherits from Object
.
The task then is to map each Scheme type into a Java class. Whether to use a standard Java class, or to write our own is a tradeoff. Using standard Java classes simplifies the passing of values between Scheme functions and existing Java methods. On the other hand, even when Java has suitable built-in classes, they usually lack functionality needed for Scheme, or are not organized in any kind of class hierarchy as in Smalltalk or Dylan. Since Java lacks standard classes corresponding to pairs, symbols, or procedures, we have to write some new classes, so we might as well write new classes whenever the existing classes lack functionality.
The Scheme boolean type is one where we use a standard Java type, in
this case Boolean
(strictly speaking
java.lang.Boolean
). The
Scheme constants #f
and #t
are
mapped into static fields (i.e.
constants) Boolean.FALSE
and
Boolean.TRUE
.
On the other hand, numbers and collections are reasonably organized into class hierarchies, which Java does not do well. So Kawa has its own classes for those. The next sections will give skeletal definitions of the classes used to to represent Scheme values.
Kawa has a hierarchy of collection classes, which extend the Java2 Collections framework. (It is possible to build Kawa so it does not require the Java2 Collections classes, which are not available in JDK 1.1.x.)
interface Sequence
{ ...;
abstract public int size();
abstract public Object get(int i);
}
Classes that implement Sequence
include
lists, vectors, and strings.
class FString implements Sequence
{ ...;
char[] value;
}
Used to implement fixed-length mutable strings (array of Unicode character). This is used to represent Scheme strings.
class FVector implements Sequence
{ ...;
Object[] value;
}
Used to implement fixed-length mutable general one-dimensional array
of Object
.
This is used to represent Scheme vectors.
public class LList extends Sequencw
{ ...;
protected LList () { }
static public LList Empty = new LList ();
}
Used to represent Scheme (linked) lists.
The empty list '()
is the special static
value List.Empty
.
Non-empty-lists are implemented using Pair
objects.
public class Pair extends LList
{ ...;
public Object car;
public Object cdr;
}
Used for Scheme pairs, i.e. all non-empty lists.
public class PairWithPosition extends Pair
{ ...;
}
Like Pair
, but includes the filename and linenumber
in the file from which the pair was read.
Future plans include more interesting collection classes,
such a sequences implemented as a seekable disk file;
lazily evaluated sequences; hash tables; APL-style
multi-dimensional arrays; stretchy buffers.
(Many of these ideas were implemented in my earlier experimental
language Q
-- see [Bothner88] and
http://per.bothner.com/software/#Q.