Objects and Values

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.