Types and declarations

A type is a named value for a set of objects with related properties. For example vector is the type for standard Scheme vectors. You can use a type to specify that a variable can only have values of the specified types:

#|kawa:5|# (define v ::vector #(3 4 5))
#|kawa:6|# v
#(3 4 5)
#|kawa:7|# (set! v 12)
/dev/stdin:7:1: warning - cannot convert literal (of type gnu.math.IntNum) to vector
Value (12) for variable 'v' has wrong type (gnu.math.IntNum) (gnu.math.IntNum cannot be cast to gnu.lists.FVector)
	at atInteractiveLevel$7.run(stdin:7)
	at gnu.expr.ModuleExp.evalModule(ModuleExp.java:302)
	at kawa.Shell.run(Shell.java:275)
	at kawa.Shell.run(Shell.java:186)
	at kawa.Shell.run(Shell.java:167)
	at kawa.repl.main(repl.java:870)
Caused by: java.lang.ClassCastException: gnu.math.IntNum cannot be cast to gnu.lists.FVector
	... 6 more

Using a type specification catches errors, and matches your programs more readable. It also can allow the Kawa compiler to generate code that runs faster.

You can use a type to check that a value is an instance of the type, using either the instance? function:

(instance? #(3 4 5) vector) ⇒ #t
(instance? '(3 4 5) vector) ⇒ #f

As a convenience, you can use a type-name followed by a “?”:

(type? val) == (instance? val type)

You can “call” a type as if it were a function. That constructs a new instance of the type.

((EXAMPLE NEEDED))

A fully-qualified Java class is a type name. So are the names of Java primitive types. So are Java array types. ((EXAMPLES NEEDED))

A type is true run-time value:

(define mytypes (list vector list string))
(instance? #(3 4 5) (car mytypes) ⇒ #t

The define-alias form is useful for defining shorter names for types, like a generalization of Java’s import statement:

(define-alias jframe javax.swing.JFrame)