[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8. Types

A type is a set of values, plus an associated set of operations valid on those values. Types are useful for catching errors ("type-checking"), documenting the programmer's intent, and to help the compiler generate better code. Types in some languages (such as C) appear in programs, but do not exist at run-time. In such languages, all type-checking is done at compile-time. Other languages (such as standard Scheme) do not have types as such, but they have predicates, which allow you to check if a value is a member of certain sets; also, the primitive functions will check at run-time if the arguments are members of the allowed sets. Other languages, including Java and Common Lisp, provide a combination: Types may be used as specifiers to guide the compiler, but also exist as actual run-time values. In Java, for each class, there is a corresponding java.lang.Class run-time object, as well as an associated type (the set of values of that class, plus its sub-classes, plus null).

Kawa, like Java, has first-class types, that is types exist as objects you can pass around at run-time. For each Java type, there is a corresponding Kawa type (but not necessarily vice versa). It would be nice if we could represent run-time type values using java.lang.Class objects, but unfortunately that does not work very well. One reason is that we need to be able to refer to types and classes that do not exist yet, because we are in the processing of compiling them. Another reason is that we want to be able to distinuish between different types that are implemented using the same Java class.

Various Kawa constructs require or allow a type to be specified. Those specifications consist of type expressions, which is evaluated to yield a type value. The current Kawa compiler is rather simple-minded, and in many places only allows simple types that the compiler can evaluate at compile-time. More specifically, it only allows simple type names that map to primitive Java types or java classes.

8.1 Standard Types  
8.2 Declaring Types of Variables  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.1 Standard Types

These types are bound to identifiers having the form <TYPENAME>. (This syntax and most of the names are as in RScheme.)

To find which Java classes these types map into, look in kawa/standard/Scheme.java.

Note that the value of these variables are instances of gnu.bytecode.Type, not (as you might at first expect) java.lang.Class.

Variable: <object>
An arbitrary Scheme value - and hence an arbitrary Java object.

Variable: <number>
The type of Scheme numbers.

Variable: <quantity>
The type of quantities optionally with units. This is a sub-type of <number>.

Variable: <complex>
The type of complex numbers. This is a sub-type of <quantity>.

Variable: <real>
The type of real numbers. This is a sub-type of <complex>.

Variable: <rational>
The type of complex numbers. This is a sub-type of <real>.

Variable: <integer>
The type of Scheme integers. This is a sub-type of <rational>.

Variable: <symbol>
The type of Scheme symbols.

Variable: <keyword>
The type of keyword values. See section 7.3 Keywords.

Variable: <list>
The type of Scheme lists (pure and impure, including the empty list).

Variable: <pair>
The type of Scheme pairs. This is a sub-type of <list>.

Variable: <string>
The type of (mutable) Scheme strings. This is not the same as (non-mutable) Java strings (which happen to be the same as <symbol>).

Variable: <character>
The type of Scheme character values. This is a sub-type of <object>, in contrast to type <char>, which is the primitive Java char type.

Variable: <vector>
The type of Scheme vectors.

Variable: <procedure>
The type of Scheme procedures.

Variable: <input-port>
The type of Scheme input ports.

Variable: <output-port>
The type of Scheme output ports.

Variable: <String>
This type name is a special case. It specifies the class <java.lang.String> (just as <symbol> does). However, coercing a value to <String> is done by invoking the toString method on the value to be coerced. Thus it "works" for all objects. It also works for #!null.

When Scheme code invokes a Java methods any parameter whose type is java.lang.String is converted as if it was decalred as a <String>.

More will be added later.

A type specifier can also be one of the primitive Java types. The numeric types <long>, <int>, <short>, <byte>, <float>, and <double> are converted from the corresponding Scheme number classes. Similarly, <char> can be converted to and from Scheme characters. The type boolean matches any object, and the result is false if and only if the actual argument is #f. The return type <void> indicates that no value is returned.

A type specifier can also be a fully-qualified Java class name (for example <java.lang.StringBuffer>). In that case, the actual argument is cast at run time to the named class. Also, <java.lang.StringBuffer[]> represents an array of references to java.lang.StringBuffer objects.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2 Declaring Types of Variables

Syntax: let ((name [:: type] init) ...) body
Declare new locals variables with the given name, initial value init, and optional type specification type. If type is specified, then the expression init is evaluated, the result coerced to type, and then assigned to the variable. If type is not specified, it defaults to <object>.

Syntax: let* ((name [:: type] init) ...) body

Syntax: letrec ((name [:: type] init) ...) body

Syntax: define [:: type] value

See also define-private, and define-constant.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Per Bothner on November, 26 2001 using texi2html