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 type:

#|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 makes your programs more readable. It can also 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, which constructs a new instance of the type. The following example shows how to construct a normal Scheme vector, and a Java array of ints:

#|kawa:1|# (vector)
#()
#|kawa:2|# (instance? (vector) vector)
#t
#|kawa:3|# (define x (int[] 1 2 3))
#|kawa:4|# x
[1 2 3]
#|kawa:5|# (instance? x int[])
#t

A fully-qualified Java class is a type name. So are the names of Java primitive types. So are Java array types, as shown above.

e.g. a JFrame is constructed by using its class name as a function:

#|kawa:6|# (javax.swing.JFrame)
javax.swing.JFrame[frame0,0,25,0x0,invalid,hidden,layout=java.awt.BorderLayout,
title=,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,
rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,
layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,
flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

A type is a 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)