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. The most used types correspond to Java classes and primitive types, but Kawa also has other non-Java types.

Type specifiers have a type expressions, and a type expression is conceptually an expression that 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.

type ::= expression
opt-type-specifier ::= [:: type]

Various Kawa constructs require or allow a type to be specified. You can use a type specifier most places where you define a variable or match a pattern. Types specifiers can appear in other placess, such as procedure return type specifiers. For example in this procedure definition, ::vector is an argument type specifier (and vec::vector is a pattern), while ::boolean is a return type specifier.

(define (vector-even? vec::vector)::boolean
  (not (odd? (vector-length vec))))
(vector-even? #(3 4 5)) ⇒ #f
(vector-even? (list 3 4 5 6)) ⇒ error