This is kawa.info, produced by makeinfo version 4.0f from
/home/bothner/Kawa/kawa/doc/kawa.texi.

START-INFO-DIR-ENTRY
* kawa: (kawa).         Kawa, the Java-based Scheme system
END-INFO-DIR-ENTRY


File: kawa.info,  Node: Format,  Prev: Ports,  Up: Input-Output

Formatted Output (Common-Lisp-style)
====================================

 - Function: format destination fmt . arguments
     An almost complete implementation of Common LISP format description
     according to the CL reference book `Common LISP' from Guy L.
     Steele, Digital Press.  Backward compatible to most of the
     available Scheme format implementations.

     Returns `#t', `#f' or a string; has side effect of printing
     according to FMT.  If DESTINATION is `#t', the output is to the
     current output port and `#!void' is returned.  If DESTINATION is
     `#f', a formatted string is returned as the result of the call.
     If DESTINATION is a string, DESTINATION is regarded as the format
     string; FMT is then the first argument and the output is returned
     as a string. If DESTINATION is a number, the output is to the
     current error port if available by the implementation. Otherwise
     DESTINATION must be an output port and `#!void' is returned.

     FMT must be a string or an instance of `gnu.text.MessageFormat' or
     `java.text.MessageFormat'.  If FMT is a string, it is parsed as if
     by `parse-format'.

 - Function: parse-format format-string
     Parses `format-string', which is a string of the form of a Common
     LISP format description.  Returns an instance of
     `gnu.text.ReportFormat', which can be passed to the `format'
     function.

   A format string passed to `format' or `parse-format' consists of
format directives (that start with `~'), and regular characters (that
are written directly to the destination).  Most of the Common Lisp (and
Slib) format directives are implemented.  Neither justification, nor
pretty-printing are supported yet.

   Plus of course, we need documentation for `format'!

Implemented CL Format Control Directives
----------------------------------------

   Documentation syntax: Uppercase characters represent the
corresponding control directive characters. Lowercase characters
represent control directive parameter descriptions.

`~A'
     Any (print as `display' does).
    `~@A'
          left pad.

    `~MINCOL,COLINC,MINPAD,PADCHARA'
          full padding.

`~S'
     S-expression (print as `write' does).
    `~@S'
          left pad.

    `~MINCOL,COLINC,MINPAD,PADCHARS'
          full padding.

`~C'
     Character.
    `~@C'
          prints a character as the reader can understand it (i.e. `#\'
          prefixing).

    `~:C'
          prints a character as emacs does (eg. `^C' for ASCII 03).

Formatting Integers
-------------------

`~D'
     Decimal.
    `~@D'
          print number sign always.

    `~:D'
          print comma separated.

    `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHD'
          padding.

`~X'
     Hexadecimal.
    `~@X'
          print number sign always.

    `~:X'
          print comma separated.

    `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHX'
          padding.

`~O'
     Octal.
    `~@O'
          print number sign always.

    `~:O'
          print comma separated.

    `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHO'
          padding.

`~B'
     Binary.
    `~@B'
          print number sign always.

    `~:B'
          print comma separated.

    `~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHB'
          padding.

`~NR'
     Radix N.
    `~N,MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHR'
          padding.

`~@R'
     print a number as a Roman numeral.

`~:@R'
     print a number as an "old fashioned" Roman numeral.

`~:R'
     print a number as an ordinal English number.

`~:@R'
     print a number as a cardinal English number.

`~P'
     Plural.
    `~@P'
          prints `y' and `ies'.

    `~:P'
          as `~P but jumps 1 argument backward.'

    `~:@P'
          as `~@P but jumps 1 argument backward.'

   COMMAWIDTH is the number of characters between two comma characters.

Formatting floating-point (real) numbers
----------------------------------------

`~F'
     Fixed-format floating-point (prints a flonum like MMM.NNN).
    `~WIDTH,DIGITS,SCALE,OVERFLOWCHAR,PADCHARF'

    `~@F'
          If the number is positive a plus sign is printed.

`~E'
     Exponential floating-point (prints a flonum like MMM.NNN`E'EE)
    `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARE'

    `~@E'
          If the number is positive a plus sign is printed.

`~G'
     General floating-point (prints a flonum either fixed or
     exponential).
    `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARG'

    `~@G'
          If the number is positive a plus sign is printed.  A slight
     difference from Common Lisp:  If the number is printed in fixed
     form and the fraction is zero, then a zero digit is printed for
     the fraction, if allowed by the WIDTH and DIGITS is unspecified.

`~$'
     Dollars floating-point (prints a flonum in fixed with signs
     separated).
    `~DIGITS,SCALE,WIDTH,PADCHAR$'

    `~@$'
          If the number is positive a plus sign is printed.

    `~:@$'
          A sign is always printed and appears before the padding.

    `~:$'
          The sign appears before the padding.

Miscellaneous formatting operators
----------------------------------

`~%'
     Newline.
    `~N%'
          print N newlines.

`~&'
     print newline if not at the beginning of the output line.
    `~N&'
          prints `~&' and then N-1 newlines.

`~|'
     Page Separator.
    `~N|'
          print N page separators.

`~~'
     Tilde.
    `~N~'
          print N tildes.

`~'<newline>
     Continuation Line.
    `~:'<newline>
          newline is ignored, white space left.

    `~@'<newline>
          newline is left, white space ignored.

`~T'
     Tabulation.
    `~@T'
          relative tabulation.

    `~COLNUM,COLINCT'
          full tabulation.

`~?'
     Indirection (expects indirect arguments as a list).
    `~@?'
          extracts indirect arguments from format arguments.

`~(STR~)'
     Case conversion (converts by `string-downcase').
    `~:(STR~)'
          converts by `string-capitalize'.

    `~@(STR~)'
          converts by `string-capitalize-first'.

    `~:@(STR~)'
          converts by `string-upcase'.

`~*'
     Argument Jumping (jumps 1 argument forward).
    `~N*'
          jumps N arguments forward.

    `~:*'
          jumps 1 argument backward.

    `~N:*'
          jumps N arguments backward.

    `~@*'
          jumps to the 0th argument.

    `~N@*'
          jumps to the Nth argument (beginning from 0)

`~[STR0~;STR1~;...~;STRN~]'
     Conditional Expression (numerical clause conditional).
    `~N['
          take argument from N.

    `~@['
          true test conditional.

    `~:['
          if-else-then conditional.

    `~;'
          clause separator.

    `~:;'
          default clause follows.

`~{STR~}'
     Iteration (args come from the next argument (a list)).
    `~N{'
          at most N iterations.

    `~:{'
          args from next arg (a list of lists).

    `~@{'
          args from the rest of arguments.

    `~:@{'
          args from the rest args (lists).

`~^'
     Up and out.
    `~N^'
          aborts if N = 0

    `~N,M^'
          aborts if N = M

    `~N,M,K^'
          aborts if N <= M <= K

Not Implemented CL Format Control Directives
--------------------------------------------

`~:A'
     print `#f' as an empty list (see below).

`~:S'
     print `#f' as an empty list (see below).

`~<~>'
     Justification.

`~:^'
Extended, Replaced and Additional Control Directives
....................................................

   These are not necesasrily implemented in Kawa!

`~I'
     print a R4RS complex number as `~F~@Fi' with passed parameters for
     `~F'.

`~Y'
     Pretty print formatting of an argument for scheme code lists.

`~K'
     Same as `~?.'

`~!'
     Flushes the output if format DESTINATION is a port.

`~_'
     Print a `#\space' character
    `~N_'
          print N `#\space' characters.

`~NC'
     Takes N as an integer representation for a character. No arguments
     are consumed. N is converted to a character by `integer->char'.  N
     must be a positive decimal number.

`~:S'
     Print out readproof.  Prints out internal objects represented as
     `#<...>' as strings `"#<...>"' so that the format output can always
     be processed by `read'.

`~:A'
     Print out readproof.  Prints out internal objects represented as
     `#<...>' as strings `"#<...>"' so that the format output can always
     be processed by `read'.

`~F, ~E, ~G, ~$'
     may also print number strings, i.e. passing a number as a string
     and format it accordingly.


File: kawa.info,  Node: Types,  Next: Objects Classes and Modules,  Prev: Input-Output,  Up: Top

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.

* Menu:

* Standard Types::
* Declaring Types of Variables::


File: kawa.info,  Node: Standard Types,  Next: Declaring Types of Variables,  Prev: Types,  Up: Types

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.  *Note 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.


File: kawa.info,  Node: Declaring Types of Variables,  Prev: Standard Types,  Up: Types

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'.


File: kawa.info,  Node: Objects Classes and Modules,  Next: Low-level functions,  Prev: Types,  Up: Top

Object, Classes and Modules
***************************

   Kawa provides various ways to define, create, and access Java
objects.  Here are the currently supported features.

   The Kawa module system is based on the features of the Java class
system.

* Menu:

* Records::
* Mangling::              Mapping Scheme names to Java names
* Allocating objects::
* Field operations::      Accessing fields of Java objects
* Method operations::     Calling Java methods from Scheme
* Defining new classes::
* Anonymous classes::
* Module classes::        Modules and how they are compiled to classes

 - Syntax: this
     Returns the "this object" - the current instance of the current
     class.  The current implementation is incomplete, not robust, and
     not well defined.  However, it will have to do for now.  Note:
     "`this'" is a macro, not a variable, so you have to write it using
     parentheses: `(this)'.  A planned extension will allow an optional
     class specifier (needed for nested clases).


File: kawa.info,  Node: Records,  Next: Mangling,  Prev: Objects Classes and Modules,  Up: Objects Classes and Modules

Records
=======

   The Record package provides a facility for users to define their own
record data types.  Records are extensions of the class `Record'.
These procedures use the Java 1.1 reflection facility.

 - Function: make-record-type type-name field-names
     Returns a "record-type descriptor", a value representing a new data
     type disjoint from all others.  The TYPE-NAME argument must be a
     string, but is only used for debugging purposes (such as the
     printed representation of a record of the new type).  The
     FIELD-NAMES argument is a list of symbols naming the "fields" of a
     record of the new type.  It is an error if the list contains any
     duplicates.

 - Function: record-constructor rtd [field-names]
     Returns a procedure for constructing new members of the type
     represented by RTD.  The returned procedure accepts exactly as
     many arguments as there are symbols in the given list,
     FIELD-NAMES; these are used, in order, as the initial values of
     those fields in a new record, which is returned by the constructor
     procedure.  The values of any fields not named in that list are
     unspecified.  The FIELD-NAMES argument defaults to the list of
     field names in the call to `make-record-type' that created the
     type represented by RTD; if the FIELD-NAMES argument is provided,
     it is an error if it contains any duplicates or any symbols not in
     the default list.


 - Function: record-predicate rtd
     Returns a procedure for testing membership in the type represented
     by RTD.  The returned procedure accepts exactly one argument and
     returns a true value if the argument is a member of the indicated
     record type; it returns a false value otherwise.


 - Function: record-accessor rtd field-name
     Returns a procedure for reading the value of a particular field of
     a member of the type represented by RTD.  The returned procedure
     accepts exactly one argument which must be a record of the
     appropriate type; it returns the current value of the field named
     by the symbol FIELD-NAME in that record.  The symbol FIELD-NAME
     must be a member of the list of field-names in the call to
     `make-record-type' that created the type represented by RTD.

 - Function: record-modifier rtd field-name
     Returns a procedure for writing the value of a particular field of
     a member of the type represented by RTD.  The returned procedure
     accepts exactly two arguments: first, a record of the appropriate
     type, and second, an arbitrary Scheme value; it modifies the field
     named by the symbol FIELD-NAME in that record to contain the given
     value.  The returned value of the modifier procedure is
     unspecified.  The symbol FIELD-NAME must be a member of the list
     of field-names in the call to `make-record-type' that created the
     type represented by RTD.

 - Function: record? obj
     Returns a true value if OBJ is a record of any type and a false
     value otherwise.

 - Function: record-type-descriptor record
     Returns a record-type descriptor representing the type of the given
     record.  That is, for example, if the returned descriptor were
     passed to `record-predicate', the resulting predicate would return
     a true value when passed the given record.

 - Function: record-type-name rtd
     Returns the type-name associated with the type represented by rtd.
     The returned value is `eqv?' to the TYPE-NAME argument given in
     the call to `make-record-type' that created the type represented by
     RTD.

 - Function: record-type-field-names rtd
     Returns a list of the symbols naming the fields in members of the
     type represented by RTD.  The returned value is `equal?' to the
     field-names argument given in the call to `make-record-type' that
     created the type represented by RTD.


File: kawa.info,  Node: Mangling,  Next: Allocating objects,  Prev: Records,  Up: Objects Classes and Modules

Mapping Scheme names to Java names
==================================

   Programs use "names" to refer to various values and procedures.  The
definition of what is a "name" is different in different programming
languages.  A name in Scheme (and other Lisp-like languages) can be
principle contain any character (if using a suitable quoting
convention), but typically names consist of "words" (one or more
letters) separated by hyphens, such as `make-temporary-file'.  Digits
and some special symbols are also used.  Standard Scheme is
case-insensitive;  this means that the names `loop', `Loop', and `LOOP'
are all the same name.  Kawa is by default case-sensitive, but we
recommend that you avoid using upper-case letters as a general rule.

   The Java language and the Java virtual machine uses names for
classes, variables, fields and methods.  These names can contain upper-
and lower-case letters, digits, and the special symbols `_' and `$'.

   Given a name in a Scheme program, Kawa needs to map that name into a
valid Java name.  A typical Scheme name such as `make-temporary-file'
is not a valid Java name.  The convention for Java names is to use
"mixed-case" words, such as `makeTemporaryFile'.  So Kawa will
translate a Scheme-style name into a Java-style name.  The basic rule
is simple:  Hyphens are dropped, and a letter that follows a hyphen is
translated to its upper-case (actually "title-case") equivalent.
Otherwise, letters are translated as is.

   Some special characters are handled specially.  A final `?' is
replaced by an _initial_ `is', with the following letter converted to
titlecase.  Thus `number?' is converted to `isNumber' (which fits with
Java conventions), and `file-exists?' is converted to `isFileExists'
(which doesn't really).  The pair `->' is translated to `$To$'.  For
example `list->string' is translated to `list$To$string'.

   Some symbols are mapped to a mnemonic sequence, starting with a
dollar-sign, followed by a two-character abbreviation.  For example,
the less-than symbol `<' is mangled as `$Ls'.  See the source code to
the `mangleName' method in the `gnu.expr.Compilation' class for the
full list.  Characters that do not have a mnemonic abbreviation are
mangled as `$' followed by a four-hex-digit unicode value.  For example
`Tamil vowel sign ai' is mangled as `$0bc8'.

   Note that this mapping may map different Scheme names to the same
Java name.  For example `string?', `String?', `is-string', `is-String',
and `isString' are all mapped to the same Java identifier `isString'.
Code that uses such "Java-clashing" names is _not_ supported.  There is
very partial support for renaming names in the case of a clash, and
there may be better support in the future.  However, some of the nice
features of Kawa depend on being able to map Scheme name to Java names
naturally, so we urge you to _not_ write code that "mixes" naming
conventions by using (say) the names `open-file' and `openFile' to name
two different objects.


File: kawa.info,  Node: Allocating objects,  Next: Method operations,  Prev: Mangling,  Up: Objects Classes and Modules

Allocating objects
==================

 - Function: make type args ...
     Constructs a new object instance of the specified TYPE, which must
     be either a `java.lang.Class' or a `<gnu.bytecode.ClassType>'.

     The ARGS ... are passed to the constructor of the class type.  If
     there is no applicable constructor, and the ARGS ...  consist of a
     set of (KEYWORD,VALUE)-pairs, then the default constructor is
     called, and each (KEYWORD,VALUE)-pair is used to set the
     correspdong slot of the result, as if by: `(slot-set! RESULT
     KEYWORD VALUE)'.

     For example, the following are all equivalent:
          (set! p (make <java.awt.Point> 3 4))
          
          (set! p (make <java.awt.Point> y: 4 x: 3))
          
          (set! p (make <java.awt.Point>))
          (slot-set! p 'x 3)
          (set! (slot-ref p 'y) 4)



File: kawa.info,  Node: Method operations,  Next: Field operations,  Prev: Allocating objects,  Up: Objects Classes and Modules

Calling Java methods from Scheme
================================

   Kawa has both a low-level and a high-level "Foreign Function
Interface", which allows you to call any (virtual or static) Java method
as if it were a Scheme procedure.

 - Function: invoke-static class name args ...
     The CLASS can be a `<java.lang.Class>', a
     `<gnu.bytecode.ClassType>', or a `<symbol>' or `<string>' that
     names a Java class.  The NAME can be `<symbol>' or `<string>' that
     names one or more methods in the Java class.  The name is
     "mangled" (*note Mangling::) into a valid Java name.

     Any public methods (static or instance) in the specified CLASS (or
     its super-classes) that match "NAME" or "NAME$V" collectively form
     a generic procedure.  When the procedure is applied to the
     argument list, the most specific applicable method is chosen
     depending on the argument list;  that method is then called with
     the given arguments.  Iff the method is an instance method, the
     first actual argument is used as the `this' argument.  If there are
     no applicable methods (or no methods at all!), or there is no
     "best" method, `WrongType' is thrown.

     ("NAME$V" is used for procedures with `#!rest' or keyword args;
     the last argument must be an array type;  all the "extra" arguments
     must be compatible with the type of the array elements.)

     An example (derived from the Skij FAQ):
          (invoke-static <java.lang.Thread> 'sleep 100)

     The behavior of interpreted code and compiled code is not
     indentical, though you should get the same result either way
     unless you have designed the classes rather strangely.  The
     details will be nailed down later, but the basic idea is that the
     compiler will "inline" the `invoke-static' call if it can pick a
     single "best" matching method.

 - Function: invoke object name args ...
     The NAME can be `<symbol>' or `<string>' that names one or more
     methods in the Java class.  The name is "mangled" (*note
     Mangling::) into a valid Java name.

     Any public methods (static or instance) in the specified CLASS (or
     its super-classes) that match "NAME" or "NAME$V" collectively form
     a generic procedure.  When the procedure is applied to the
     argument list, the most specific applicable method is chosen
     depending on the argument list;  that method is then called with
     the given arguments.  Iff the method is an instance method, the
     OBJECT is used as the `this' argument; otherwise OBJECT is
     prepended to the ARGS list.  If there are no applicable methods
     (or no methods at all!), or there is no "best" method, `WrongType'
     is thrown.

     ("NAME$V" is used for procedures with `#!rest' or keyword args;
     the last argument must be an array type;  all the "extra" arguments
     must be compatible with the type of the array elements.)

     The behavior of interpreted code and compiled code is not
     indentical, though you should get the same result either way
     unless you have designed the classes rather strangely.  The
     details will be nailed down later, but the basic idea is that the
     compiler will "inline" the `invoke-static' call if it can pick a
     single "best" matching method.

     If the compiler cannot determine the method to call (assuming the
     method name is constant), the compiler has to generate code at
     run-time to find the correct method.  This is much slower, so the
     compiler will print a warning.  To avoid a waning, you can use a
     type declaration, or insert a cast:
          (invoke (as <java.util.Date> my-date) 'setDate cur-date)

 - Function: class-methods class name
     Return a generic function containing those methods of CLASS that
     match the name NAME, in the sense of `invoke-static'.  Same as:
          (lambda args (apply invoke-static (cons class (cons name args))))

   Some examples using these functions are `vectors.scm' and
`characters.scm' the directory `kawa/lib' in the Kawa sources.


File: kawa.info,  Node: Field operations,  Next: Defining new classes,  Prev: Method operations,  Up: Objects Classes and Modules

Accessing fields of Java objects
================================

   Kawa has both a high-level interface and a low-level interface for
accessing the fields of Java objects and static fields.  The
lower-level interfaces are macros that return functions.  These
functions can be inlined, producing efficient code.  The higher-level
functions are less verbose and more convenient.  However, they can only
access public fields.

 - Function: field object fieldname
     Get the instance field with the given FIELDNAME from the given
     OBJECT.  Returns the value of the field, which must be public.
     This procedure has a `setter', and so can be used as the first
     operand to `set!'.

     The field name is "mangled" (*note Mangling::) into a valid Java
     name.  If there is no accessible field whose name is `"FIELDNAME"',
     we look for a no-argument method whose name is `"getFIELDNAME"'.

     If OBJECT is a primitive Java array, then FIELDNAME can only be
     `'length', and the result is the number of elements of the array.

 - Function: static-field class fieldname
     Get the static field with the given FIELDNAME from the given
     CLASS.  Returns the value of the field, which must be public.
     This procedure has a `setter', and so can be used as the first
     operand to `set!'.

   Examples:
     (static-field <java.lang.System> 'err)
     ;; Copy the car field of b into a.
     (set! (field a 'car) (field b 'car))

 - Function: slot-ref object fieldname
     A synonym for `(field OBJECT FIELDNAME)'.

 - Function: slot-set! object fieldname value
     A synonym for `(set! (field OBJECT FIELDNAME) VALUE)'.


File: kawa.info,  Node: Defining new classes,  Next: Anonymous classes,  Prev: Field operations,  Up: Objects Classes and Modules

Defining new classes
====================

   Kawa provides various mechanisms for defining new classes.  The
`define-class' and `define-simple-class' forms will usually be the
preferred mechanisms.  They have basically the same syntax, but have a
couple of differences.  `define-class' allows multiple inheritance as
well as true nested (first-class) class objects.  However, the
implementation is more complex: code using it is slightly slower, and
the mapping to Java classes is a little less obvious.   (Each Scheme
class is implemented as a pair of an interface and an implementation
class.)  A class defined by `define-simple-class' is slightly more
efficient, and it is easier to access it from Java code.

   The syntax of `define-class' are mostly compatible with that in the
Guile and Stk dialects of Scheme.

   An implementation restriction is that you should only use
`define-class' and `define-simple-class' in compiled code.  The problem
involves Java class loaders.

 - Syntax: define-class name (supers ...) field-or-method-decl ...
 - Syntax: define-simple-class name (supers ...) field-or-method-decl
          ...
          FIELD-OR-METHOD = FIELD-DECL | METHOD-DECL
          FIELD-DECL = (FNAME [:: FTYPE] [OPTION-KEYWORD OPTION-VALUE]*)
          METHOD-DECL = ((METHOD-NAME FORMAL-ARGUMENTS) [:: RTYPE] BODY)
     Defines a new class named NAME.  If `define-simple-class' is used,
     creates a normal Java class named NAME in the current package.
     (If NAME has the form `<xyx>' the Java implementation type is
     named `xyz'.)  If `define-class' the implementation is
     unspecified.  In most cases, the compiler creates a class pair,
     consisting of a Java interface and a Java implementation class.

     The class inherits from the classes and interfaces listed in
     SUPERS.  This is a list of names of classes that are in scope
     (perhaps imported using `require'), or names for existing classes
     or interfaces surrounded by `<>', such as `<gnu.lists.Sequence>'.
     If `define-simple-class' is used, at most one of these may be the
     name of a normal Java class or classes defined using
     `define-simple-class'; the rest must be interfaces or classes
     defined using `define-class'.  If `define-class' is used, _all_ of
     the classes listed in SUPERS should be interfaces or classes
     defined using `define-class'.

     Each FIELD-DECL declares a public instance "slot" (field) with the
     given FNAME.  If FTYPE is specified it is the type of the slot.
     The following OPTION-KEYWORDs are implemented:
    `type:' FTYPE
          Specifies that FTYPE is the type of (the values of) the field.
          Equivalent to `:: FTYPE'.

    `allocation:' `class:'
          Specifies that there should be a single slot shared between
          all instances of the class (and its sub-classes).  Not yet
          implemented for `define-class', only for
          `define-simple-class'.  In Java terms this is a `static'
          field.

    `allocation:' `instance:'
          Specifies that each instance has a separate value "slot", and
          they are not shared. In Java terms, this is a non-`static'
          field.  This is the default.

    `init-form:' EXPR
          An expression used to initialize the slot.  The lexical
          environment of the EXPR is that of the `define-class' or
          `define-simple-class'.  (This is not quite true in the current
          implementation, as the names of fields and methods of this
          class are visible.)

    `init-value:' VALUE
          A value expression used to initialize the slot.  For now this
          is synonymous with INIT-FORM:, but that may change (depending
          on what other implementation do), so to be safe only use
          `init-value:' with a literal.

    `init-keyword:' `NAME:'
          A keyword that that can be used to initialize instance in
          `make' calls.  For now, this is ignored, and NAME should be
          the same as the field's FNAME.  `static' field.

     Each METHOD-DECL declares a public non-static method, whose name
     is METHOD-NAME.  (If METHOD-NAME is not a valid Java method name,
     it is mapped to something reasonable.  For example `foo-bar?' is
     mapped to `isFooBar'.)  The types of the method arguments can be
     specified in the FORMAL-ARGUMENTS.  The return type can be
     specified by RTYPE, or is otherwise the type of the BODY.
     Currently, the FORMAL-ARGUMENTS cannot contain optional, rest, or
     keyword parameters.  (The plan is to allow optional parameters,
     implemented using multiple overloaded methods.)

     The scope of the BODY of a method includes the FIELD-DECLs of the
     object.  It does include the surrounding lexical scope.  It
     sort-of also includes the declared methods, but this is not
     working yet.

   A simple example:
     (define-simple-class <2d-vector> ()
       (x type: <double> init-value: 0.0 init-keyword: x:)
       (y type: <double> init-value: 0.0 init-keyword: y:)
       ((add (other :: <2d-vector>)) :: <2d-vector>
        ;; Kawa compiles this using primitive Java types!
        (make <2d-vector>
          x: (+ x (slot-ref other 'x))
          y: (+ y (slot-ref other 'y))))
       ((scale (factor :: <double>)) :: <2d-vector>
        ;; Unfortunately, multiply is not yet optimized as addition is.
        (make <2d-vector> x: (* factor x) y: (* factor y))))
     
     (define-simple-class <3d-vector> (<2d-vector>)
       (z type: <double> init-value: 0.0 init-keyword: z:)
       ((scale (factor :: <double>)) :: <2d-vector>
        ;; Note we cannot override the return type to <3d-vector>
        ;; because Java does not allow that.  Should hide that. .
        (make <3d-vector>
          ;; Unfortunately, slot names of inherited classes are not visible.
          ;; Until this is fixed, use slot-ref.
          x: (* factor (slot-ref (this) 'x))
          y: (* factor (slot-ref (this) 'y))
          z: (* factor z))))


File: kawa.info,  Node: Anonymous classes,  Next: Module classes,  Prev: Defining new classes,  Up: Objects Classes and Modules

Anonymous classes
=================

 - Syntax: object (supers ...) field-or-method-decl ...
     Returns a new instance of an anonymous (inner) class.  The syntax
     is similar to `define-class'.
          FIELD-OR-METHOD = FIELD-DECL | METHOD-DECL
          FIELD-DECL = (FNAME [[[::] FTYPE] FINIT])
              | (FNAME [:: FTYPE] [OPTION-KEYWORD OPTION-VALUE]*)
          METHOD-DECL = ((METHOD-NAME FORMAL-ARGUMENTS) [[::] RTYPE] BODY)

     Returns a new instance of a unique (anonymous) class.  The class
     inherits from the list of SUPERS, where at most one of the
     elements should be the base class being extended from, and the rest
     are interfaces.

     This is roughly equivalent to:
          (begin
            (define-name HNAME (SUPERS ...) FIELD-OR-METHOD-DECL ...)
            (make HNAME))

     A FIELD-DECL is as for `define-class', except that we also allow
     an abbreviated syntax.  Each FIELD-DECL declares a public instance
     field.  If FTYPE is given, it specifies the type of the field.  If
     FINIT is given, it is an expression whose value becomes the
     initial value of the field.  The FINIT is evaluated at the same
     time as the `object' expression is evaluated, in a scope where all
     the FNAMEs are visible.

     A METHOD-DECL is as for `define-class'.


File: kawa.info,  Node: Module classes,  Prev: Anonymous classes,  Up: Objects Classes and Modules

Modules and how they are compiled to classes
============================================

   A "module" is a set of definitions that the module "exports", as
well as some "actions" (expressions evaluated for their side effect).
The top-level forms in a Scheme source file compile a module; the
source file is the "module source".  When Kawa compiles the module
source, the result is the "module class".  Each exported definition is
translated to a public field in the module class.

   There are two kinds of module class: A "static module" is a class
(or gets compiled to a class) all of whose public fields a static, and
that does not have a public constructor.  A JVM can only have a single
global instance of a static module.  An "instance module" has a public
default constructor, and usually has at least one non-static public
field.  There can be multiple instances of an instance module; each
instance is called a "module instance".  However, only a single
instance of a module can be "registered" in an environment, so in most
cases there is only a single instance of instance modules.  Registering
an instance in an environment means creating a binding mapping a magic
name (derived from the class name) to the instance.

   In fact, any Java class class that has the properties of either an
instance module or a static module, is a module, and can be loaded or
imported as such;  the class need not have written using Scheme.

Name visibility
---------------

   The definitions that a module exports are accessible to other
modules.  These are the "public" definitions, to use Java terminology.
By default, all the identifiers declared at the top-level of a module
are exported, except those defined using `define-private'.  However, a
major purpose of using modules is to control the set of names exported.
One reason is to reduce the chance of accidental name conflicts
between separately developed modules.  An even more important reason is
to enforce an interface:  Client modules should only use the names that
are part of a documented interface, and should not use internal
implementation procedures (since those may change).

   If there is a `module-export' declaration in the module, then only
those names listed in a `module-export' are exported.  There can be
more than one `module-export', and they can be anywhere in the Scheme
file.  As a matter of good style, I recommend a single `module-export'
near the beginning of the file.

 - Syntax: module-export name ...
     Make the definition for each NAME be exported.  Note that it is an
     error if there is no definition for NAME in the current module, or
     if it is defined using `define-private'.

   In this module, `fact' is public and `worker' is private:
     (module-export fact)
     (define (worker x) ...)
     (define (fact x) ...)

   Alternatively, you can write:
     (define-private (worker x) ...)
     (define (fact x) ...)

Definitions
-----------

   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
     Definites NAME to have the given VALUE.  The value is readonly,
     and you cannot assign to it.  (This is not fully enforced.)  If
     the definition is at module level, then the compiler will create a
     `final' field with the given name and type.  The VALUE is
     evaluated as normal; however, if it is a compile-time constant, it
     defaults to being static.

How a module becomes a class
----------------------------

   If you want to just use a Scheme module as a module (i.e. `load' or
`require' it), you don't care how it gets translated into a module
class.  However, Kawa gives you some control over how this is done, and
you can use a Scheme module to define a class which you can use with
other Java classes.  This style of class definition is an alternative
to `define-class' [not yet implemented] which lets you define classes
and instances fairly conveniently.

   The default name of the module class is the main part of the
filename of the Scheme source file (with directories and extensions
sripped off).  That can be overridden by the `-T' Kawa command-line
flag.  The package-prefix specified by the `-P' flag is prepended to
give the fully-qualified class name.

 - Syntax: module-name <name>
     Sets the name of the generated class, overriding the default.  If
     there is no `.' in the NAME, the package-prefix (specified by the
     `-P' Kawa command-line flag) is prepended.

   By default, the base class of the generated module class is
unspecified; you cannot count on it being more specific than `Object'.
However, you can override it with `module-extends'.

 - Syntax: module-extends <class>
     Specifies that the class generated from the immediately surrounding
     module should extend (be a sub-class of) the class `<CLASS>'.

 - Syntax: module-implements <interface> ...
     Specifies that the class generated from the immediately surrounding
     module should implement the interfaces listed.

   Note that the compiler does _not_ currently check that all the
abstract methods requires by the base class or implemented interfaces
are actually provided, and have the correct signatures.  This will
hopefully be fixed, but for now, if you are forgot a method, you will
probably get a verifier error

   For each top-level exported definition the compiler creates a
corresponding public field with a similar (mangled) name.  By default,
there is some indirection:  The value of the Scheme variable is not
that of the field itself.  Instead, the field is a
`gnu.mapping.Binding' object, and the value Scheme variable is defined
to be the value stored in the `Binding'.  Howewer, if you specify an
explicit type, then the field will have the specified type, instead of
being a `Binding'.  The indirection using `Binding' is also avoided if
you use `define-constant'.

   If the Scheme definition defines a procedure (which is not
re-assigned in the module), then the compiler assumes the variable as
bound as a constant procedure.  The compiler generates one or more
methods corresponding to the body of the Scheme procedure. It also
generates a public field with the same name; the value of the field is
an instance of a subclass of `<gnu.mapping.Procedure>' which when
applied will execute the correct method (depending on the actual
arguments).  The field is used when the procedure used as a value (such
as being passed as an argument to `map'), but when the compiler is able
to do so, it will generate code to call the correct method directly.

   You can control the signature of the generated method by declaring
the parameter types and the return type of the method.  See the applet
(*note Applet compilation::) example for how this can be done.  If the
procedures has optional parameters, then the compiler will generate
multiple methods, one for each argument list length.  (In rare cases
the default expression may be such that this is not possible, in which
case an "variable argument list" method is generated instead.  This
only happens when there is a nested scope _inside_ the default
expression, which is very contrived.)  If there are `#!keyword' or
`#!rest' arguments, the compiler generate a "variable argument list"
method.  This is a method whose last parameter is either an array or a
`<list>', and whose name has `$V' appended to indicate the last
parameter is a list.

   Top-leval macros (defined using either `define-syntax' or
`defmacro') create a field whose type is currently a sub-class of
`kawa.lang.Syntax';  this allows importing modules to detect that the
field is a macro and apply the macro at compile time.

 - Syntax: module-static name ...
 - Syntax: module-static `#t'
 - Syntax: module-static `#f'
     Control whether the generated fields and methods are static.  If
     `#t' is specified, then the module will be a static module, _all_
     definitions will be static, and the module body is evaluated in
     the class's static initializer.  Otherwise, the module is an
     instance module.  However, the NAMEs that are explicitly listed
     will be compiled to static fields and methods.  If `#f' is
     specified, then all exported names will be compiled to non-static
     (instance) fields and methods.

     By default, if no `module-static' is specified, the following
     rules apply:
       1. If there is a `module-extends' or `module-implements'
          declaration, then `(module-static #f)' is implied.

       2. If the `--module-static' command-line parameter is specified,
          then `(module-static #t)' is implied.

       3. (Not yet implemented: If there are no top-level actions and
          all definitions are procedure definitions, macro definitions,
          or constant definitions, then `(module-static #t)' is
          implied.)

       4. Otherwise, a method will be static iff it doesn't need to
          reference non-static fields or methods of the module
          instance.  In that case, the corresponding field will also be
          static.

     Note `(module-static #t)' usually produces more efficient code,
     and is recommended if a module contains only procedure or macro
     definitions.  (This may become the default.)  However, a static
     module means that all environments in a JVM share the same
     bindings, which you may not want if you use multiple top-level
     environments.

   Unfortuntely, the Java class verifier does not allow fields to have
arbitrary names.  Therefore, the name of a field that represents a
Scheme variable is "mangled" (*note Mangling::) into an acceptable Java
name.  The implementation can recover the original name of a field `X'
as `((gnu.mapping.Named) X).getName()' because all the standard
compiler-generate field types implemented the `Named' interface.

   The top-level actions of a module will get compiled to a `run'
method.  If there is an explicit `method-extends', then the module
class will also automatically implement `java.lang.Runnable'.
(Otherwise, the class does not implement `Runnable', since in that case
the `run' method return an `Object' rather than `void'.  This will
likely change.)

Requiring (importing) a module
------------------------------

   You can import a module into the current namespace with `require'.

 - Syntax: require modulespec
     The MODULESPEC can be either a `<CLASSNAME>' or a `'FEATURENAME'.
     In either case the names exported by the specified module (class)
     are added to the current set of visible names.

     If MODULESPEC is `<CLASSNAME>' where CLASSNAME is an instance
     module (it has a public default constructor), and if no module
     instance for that class has been registered in the current
     environment, then a new instance is created and registered (using
     a "magic" identifier).  If the module class either inherits from
     `gnu.expr.ModuleBody' or implements `java.lang.Runnable' then the
     corresponding `run' method is executed.  (This is done _after_ the
     instance is registered so that cycles can be handled.)  These
     actions (creating, registering, and running the module instance)
     are done both at compile time and at run time, if necessary.

     All the public fields of the module class are then incorporated in
     the current set of local visible names in the current module.
     This is done at compile time - no new bindings are created at
     run-time (except for the magic binding used to register the module
     instance), and the imported bindings are private to the current
     module.  References to the imported bindings will be compiled as
     field references, using the module instance (except for static
     fields).

     If the MODULESPEC is `'FEATURENAME' then the FEATURENAME is looked
     up (at compile time) in the "feature table" which yields the
     implementing `<CLASSNAME>'.

   For some examples, you may want to look in the `gnu/kawa/slib'
directory.

