Definitions

A variable definition binds one or more identifiers and specifies an initial value for each of them. The simplest kind of variable definition takes one of the following forms:

Syntax: ! pattern expression

Evaluate expression, and match the result against pattern. Defining variables in pattern becomes bound in the current (surrounding) scope.

This is similar to define-constant except generalized to a pattern.

(! [x y] (vector 3 4))
(format "x is ~w and y is ~w" x y) ⇒ "x is 3 and y is 4"

Syntax: define name [:: type] expression

Evaluate the expression, optionally converting it to type, and bind the name to the result.

Syntax: define (name formal-arguments) (annotation | option-pair)* opt-return-type body

Syntax: define (name . rest-arg) (annotation | option-pair)* opt-return-type body

Bind the name to a function definition. The form:

(define (name formal-arguments) option-pair* opt-return-type body)

is equivalent to:

(define name (lambda formal-arguments) name: name option-pair* opt-return-type body))

while the form:

(define (name . rest-arg) option-pair* opt-return-type body)

is equivalent to:

(define name (lambda rest-arg) name: name option-pair* opt-return-type body))

You can associate annotations with name. A field annotation will be associated with the generated field; a method annotation will be associated with the generated method(s).

In addition to define (which can take an optional type specifier), Kawa has some extra definition forms.

Syntax: define-private name [:: type] value

Syntax: define-private (name formals) body

Same as define, except that name is not exported.

Syntax: define-constant name [:: type] value

Syntax: define-early-constant name [:: type] value

Defines name to have the given value. The value is readonly, and you cannot assign to it. (This is not fully enforced.)

If define-early-constant is used or the value is a compile-time constant, then the compiler will create a final field with the given name and type, and evaluate value in the module’s class initializer (if the definition is static) or constructor (if the definition is non-static), before other definitions and expressions. Otherwise, the value is evaluated in the module body where it appears.

If the value is a compile-time constant, then the definition defaults to being static.

Syntax: define-variable name [:: type] [init]

If init is specified and name does not have a global variable binding, then init is evaluated, and name bound to the result. Otherwise, the value bound to name does not change. (Note that init is not evaluated if name does have a global variable binding.)

Also, declares to the compiler that name will be looked up in the per-thread dynamic environment. This can be useful for shutting up warnings from --warn-undefined-variable.

This is similar to the Common Lisp defvar form. However, the Kawa version is (currently) only allowed at module level.

For define-namespace and define-private-namespace see Namespaces.