This is kawa.info, produced by makeinfo version 4.5 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: Named output formats,  Next: Files,  Up: Input-Output

   The `--output-format' (or `--format') command-line switch can be
used to override the default format for how values are printed on the
standard output.  This format is used for values printed by the
read-eval-print interactive interface.  It is also used to control how
values are printed when Kawa evaluates a file named on the command line
(using the `-f' flag or a just a script name).  (It also effects
applications compiled with the `--main' flag.)  It currently effects
how values are printed by a `load', though that may change.

   The default format depends on the current programming language.  For
Scheme, the default is `--scheme' for read-eval-print interaction, and
`--ignore' for files that are loaded.

   The formats currently supported include the following:
`scheme'
     Values are printed in a format matching the Scheme programming
     language, as if using `display'.  "Groups" or "elements" are
     written as lists.

`readable-scheme'
     Like `scheme', as if using `write': Values are generally printed
     in a way that they can be read back by a Scheme reader.  For
     example, strings have quotation marks, and character values are
     written like `#\A'.

`elisp'
     Values are printed in a format matching the Emacs Lisp programming
     language.  Mostly the same as `scheme'.

`readable-elisp'
     Like `elisp', but values are generally printed in a way that they
     can be read back by an Emacs Lisp reader.  For example, strings
     have quotation marks, and character values are written like `?A'.

`clisp'
`commonlisp'
     Values are printed in a format matching the Common Lisp
     programming language, as if written by `princ'.  Mostly the same
     as `scheme'.

`readable-clisp'
`readable-commonlisp'
     Like `clisp', but as if written by `prin1': values are generally
     printed in a way that they can be read back by a Common Lisp
     reader.  For example, strings have quotation marks, and character
     values are written like `#\A'.

`xml'
     Values are printed in XML format.  "Groups" or "elements" are
     written as using xml element syntax.  Plain characters (such as
     `<') are escaped (such as `&lt;').

`xhtml'
     Same as `xml', but follows the xhtml compatibility guidelines.

`html'
     Values are printed in HTML format.  Mostly same as `xml' format,
     but certain element without body, are written without a closing
     tag.   For example `<img>' is written without `</img>', which
     would be illegal for html, but required for xml.  Plain characters
     (such as `<') are not escaped inside `<script>' or `<style>'
     elements.

`cgi'
     The output should be a follow the CGI standards.  I.e. assume that
     this script is invoked by a web server as a CGI script/program,
     and that the output should start with some response header,
     followed by the actual response data.  To generate the response
     headers, use the `response-header' function.  If the
     `Content-type' response header has not been specified, and it is
     required by the CGI standard, Kawa will attempt to infer an
     appropriate `Content-ty[e' depending on the following value.

`ignore'
     Top-level values are ignored, instead of printed.


File: kawa.info,  Node: Files,  Next: Ports,  Prev: Named output formats,  Up: Input-Output

File System Interface
=====================

 - Function: file-exists? filename
     Returns true iff the file named FILENAME actually exists.

 - Function: file-directory? filename
     Returns true iff the file named FILENAME actually exists and is a
     directory.

 - Function: file-readable? filename
     Returns true iff the file named FILENAME actually exists and can
     be read from.

 - Function: file-writable? filename
     Returns true iff the file named FILENAME actually exists and can
     be writen to.  (Undefined if the FILENAME does not exist, but the
     file can be created in the directory.)

 - Function: delete-file filename
     Delete the file named FILENAME.

 - Function: rename-file oldname newname
     Renames the file named OLDNAME to NEWNAME.

 - Function: copy-file oldname newname-from path-to
     Copy the file named OLDNAME to NEWNAME.  The return value is
     unspecified.

 - Function: create-directory dirname
     Create a new directory named DIRNAME.  Unspecified what happens on
     error (such as exiting file with the same name).  (Currently
     returns `#f' on error, but may change to be more compatible with
     scsh.)

 - Function: system-tmpdir
     Return the name of the default directory for temporary files.

 - Function: make-temporary-file [format]
     Return a file with a name that does not match any existing file.
     Use FORMAT (which defaults to `"kawa~d.tmp"') to generate a unique
     filename in `(system-tmpdir)'.  The current implementation is
     _not_ safe from race conditions; this will be fixed in a future
     release (using Java2 features).


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

Ports
=====

 - Function: current-error-port
     Return the port to which errors and warnings should be sent (the
     "standard error" in Unix and C terminology).

 - Function: read-line [port [handle-newline]]
     Reads a line of input from PORT.  The HANDLE-NEWLINE parameter
     determines what is done with terminating end-of-line delimiter.
     The default, `'trim', ignores the delimiter; `'peek' leaves the
     delimiter in the input stream; `'concat' appends the delimiter to
     the returned value; and `'split' returns the delimiter as a second
     value.  You can use the last three options to tell if the string
     was terminated by end-or-line or by end-of-file.

 - Function: open-input-string string
     Takes a string and returns an input port that delivers characters
     from the string. The port can be closed by `close-input-port',
     though its storage will be reclaimed by the garbage collector if
     it becomes inaccessible.

          (define p
            (open-input-string "(a . (b c . ())) 34"))
          
          (input-port? p)                 -->  #t
          (read p)                        -->  (a b c)
          (read p)                        -->  34
          (eof-object? (peek-char p))     -->  #t

 - Function: open-output-string
     Returns an output port that will accumulate characters for
     retrieval by `get-output-string'.  The port can be closed by the
     procedure `close-output-port', though its storage will be
     reclaimed by the garbage collector if it becomes inaccessible.
          (let ((q (open-output-string))
            (x '(a b c)))
              (write (car x) q)
              (write (cdr x) q)
              (get-output-string q))        -->  "a(b c)"

 - Function: get-output-string output-port
     Given an output port created by `open-output-string', returns a
     string consisting of the characters that have been output to the
     port so far.

 - Function: call-with-input-string string proc
     Create an input port that gets its data from STRING, call PROC
     with that port as its one argument, and return the result from the
     call of PROC

 - Function: call-with-output-string proc
     Create an output port that writes its data to a STRING, and call
     PROC with that port as its one argument.  Return a string
     consisting of the data written to the port.

 - Function: force-output [port]
     Forces any pending output on PORT to be delivered to the output
     device and returns an unspecified value.  If the PORT argument is
     omitted it defaults to the value returned by
     `(current-output-port)'.

   An interactive input port has a prompt procedure associated with it.
The prompt procedure is called before a new line is read.  It is passed
the port as an argument, and returns a string, which gets printed as a
prompt.

 - Function: input-port-prompter port
     Get the prompt procedure associated with PORT.

 - Function: set-input-port-prompter! port prompter
     Set the prompt procedure associated with PORT to PROMPTER, which
     must be a one-argument procedure taking an input port, and
     returning a string.

 - Function: default-prompter port
     The default prompt procedure.  It returns `"#|kawa:L|# "', where L
     is the current line number of PORT.  When reading a continuation
     line, the result is `"#|C---:L|# "', where `C' is the character
     returned by `(input-port-read-state PORT)'.  The prompt has the
     form of a comment to make it easier to cut-and-paste.

 - Function: port-column input-port
 - Function: port-line input-port
     Return the current column number or line number of INPUT-PORT,
     using the current input port if none is specified.  If the number
     is unknown, the result is `#f'.  Otherwise, the result is a
     0-origin integer - i.e. the first character of the first line is
     line 0, column 0.  (However, when you display a file position, for
     example in an error message, we recommend you add 1 to get
     1-origin integers.  This is because lines and column numbers
     traditionally start with 1, and that is what non-programmers will
     find most natural.)

 - Function: set-port-line! port line
     Set (0-origin) line number of the current line of PORT to NUM.

 - Function: input-port-line-number port
     Get the line number of the current line of PORT, which must be a
     (non-binary) input port.  The initial line is line 1.  Deprecated;
     replaced by `(+ 1 (port-line PORT))'.

 - Function: set-input-port-line-number! port num
     Set line number of the current line of PORT to NUM.  Deprecated;
     replaced by `(set-port-line! PORT (- NUM 1))'.

 - Function: input-port-column-number port
     Get the column number of the current line of PORT, which must be a
     (non-binary) input port.  The initial column is column 1.
     Deprecated; replaced by `(+ 1 (port-column PORT))'.

 - Function: input-port-read-state port
     Returns a character indicating the current `read' state of the
     PORT.  Returns `#\Return' if not current doing a READ, `#\"' if
     reading a string;  `#\|' if reading a comment;  `#\(' if inside a
     list; and `#\Space' when otherwise in a `read'.  The result is
     intended for use by prompt prcedures, and is not necessarily
     correct except when reading a new-line.

 - Variable: symbol-read-case
     A symbol that controls how `read' handles letters when reading a
     symbol.  If the first letter is `U', then letters in symbols are
     upper-cased.  If the first letter is `D' or `L', then letters in
     symbols are down-cased.  If the first letter is `I', then the case
     of letters in symbols is inverted.  Otherwise (the default), the
     letter is not changed.  (Letters following a `\' are always
     unchanged.)

 - Variable: port-char-encoding
     Controls how bytes in external files are converted to/from internal
     Unicode characters.  Can be either a symbol or a boolean.  If
     `port-char-encoding' is `#f', the file is assumed to be a binary
     file and no conversion is done.  Otherwise, the file is a text
     file.  The default is `#t', which uses a locale-dependent
     conversion.  If `port-char-encoding' is a symbol, it must be the
     name of a character encoding known to Java.  For all text files
     (that is if `port-char-encoding' is not `#f'), on input a
     `#\Return' character or a `#\Return' followed by `#\Newline' are
     converted into plain `#\Newline'.

     This variable is checked when the file is opened;  not when
     actually reading or writing.  Here is an example of how you can
     safely change the encoding temporarily:
          (define (open-binary-input-file name)
            (fluid-let ((port-char-encoding #f)) (open-input-file name)))


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:

* Record types::          Defining Record Types
* Dynamic records::       Creating New Record Types On-the-fly
* 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: Record types,  Next: Dynamic records,  Prev: Objects Classes and Modules,  Up: Objects Classes and Modules

   The `define-record-type' form can be used for creating new data
types, called record types. A predicate, constructor, and field
accessors and modifiers are defined for each record type.  The
`define-record-type' feature is specified by SRFI-9
(http://srfi.schemers.org/srfi-9/srfi-9.html), which is implemented by
many modern Scheme implementations.

 - Syntax: define-record-type TYPE-NAME (CONSTRUCTOR-NAME FIELD-TAG
          ...) PREDICATE-NAME (FIELD-TAG ACCESSOR-NAME [MODIFIER-NAME])
          ...
     The form `define-record-type' is generative: each use creates a new
     record type that is distinct from all existing types, including
     other record types and Scheme's predefined types. Record-type
     definitions may only occur at top-level (there are two possible
     semantics for `internal' record-type definitions, generative and
     nongenerative, and no consensus as to which is better).

     An instance of `define-record-type' is equivalent to the following
     definitions:
        * The TYPE-NAME is bound to a representation of the record type
          itself.

        * The CONSTRUCTOR-NAME is bound to a procedure that takes as
          many arguments as there are FIELD-TAGs in the
          `(CONSTRUCTOR-NAME ...)' subform and returns a new TYPE-NAME
          record. Fields whose tags are listed with CONSTRUCTOR-NAME
          have the corresponding argument as their initial value. The
          initial values of all other fields are unspecified.

        * The PREDICATE-NAME is a predicate that returns `#t' when
          given a value returned by CONSTRUCTOR-NAME and `#f' for
          everything else.

        * Each ACCESSOR-NAME is a procedure that takes a record of type
          TYPE-NAME and returns the current value of the corresponding
          field.  It is an error to pass an accessor a value which is
          not a record of the appropriate type.

        * Each MODIFIER-NAME is a procedure that takes a record of type
          TYPE-NAME and a value which becomes the new value of the
          corresponding field.  The result (in Kawa) is the empty value
          `#!void'.  It is an error to pass a modifier a first argument
          which is not a record of the appropriate type.

     Set!ing the value of any of these identifiers has no effect on the
     behavior of any of their original values.

   Here is an example of how you can define a record type named `pare'
with two fields `x' and `y':
     (define-record-type pare
       (kons x y)
       pare?
       (x kar set-kar!)
       (y kdr))

   The above defines `kons' to be a constructor, `kar' and `kdr' to be
accessors, `set-kar!' to be a modifier, and `pare?' to be a predicate
for `pare's.
     (pare? (kons 1 2))        --> #t
     (pare? (cons 1 2))        --> #f
     (kar (kons 1 2))          --> 1
     (kdr (kons 1 2))          --> 2
     (let ((k (kons 1 2)))
       (set-kar! k 3)
       (kar k))                --> 3

   The Kawa compiler creates a new Java class with a name derived from
the TYPE-NAME.  If the TYPE-NAME is valid Java class name, that becomes
the name of the Java class.  If the TYPE-NAME has the form `<NAME>'
(for example `<pare>'), then NAME is used, if possible, for the Java
class name.  Otherwise, the name of the Java class is derived by
"mangling" the TYPE-NAME.  In any case, the package is the same as that
of the surrounding module.

   Kawa generates efficient code for the PREDICATE-NAME, ACCESSOR-NAME,
and MODIFIER-NAME functions.  The CONSTRUCTOR-NAME currently compiles
into code using run-time reflection, but hopefully that will get fixed.


File: kawa.info,  Node: Dynamic records,  Next: Mangling,  Prev: Record types,  Up: Objects Classes and Modules

Creating New Record Types On-the-fly
====================================

   Calling the `make-record-type' procedure creates a new record data
type at run-time, without any compile-time support.  It is primarily
provided for compatibility; in most cases it is better to use the
`define-record-type' form (*note Record types::).

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

   Records are extensions of the class `Record'.  These procedures use
the Java 1.1 reflection facility.


File: kawa.info,  Node: Mangling,  Next: Allocating objects,  Prev: Dynamic 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 in
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.

   The above mangling is used to generate Java method names.  Each
top-level definition is also mapped to a Java field.  The name of this
field is also mangled, but using a mostly reversible mapping:  The
Scheme function `file-exists?' is mapped to the method name
`file$Mnexists$Qu'.  Because `$' is used to encode special characters,
you should avoid using it in names in your source file.


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
================================

   You can call a Java method as if it were a Scheme procedure using
various mechanisms.  The most convenient way to do it is to use
`define-namespace' to define an alias for a Java class:
     (define-namespace Int32 "class:java.lang.Integer")
   In this example the name `Int32' is a "namespace alias" for the
namespace whose full name is `"class:java.lang.Integer"'.  The full
name should be the 6 characters `"class:"' followed by the
fully-qualified name of a Java class.  You can name a method using a
"qualified name" containing a colon.  The part of the name before the
colon is a namespace alias (in this case `Int32'), and the part of the
name after the colon is the method name.  For example:
     (Int32:toHexString 255) => ff
   This invokes the static method `toHexString' in the Java class
`java.lang.Integer', passing it the argument `255', and returning the
Java String `"ff"'.  (Note this is not the same as a Scheme string!)

   You can use the method name `new' to construct new objects:
     (Int32:new '|255|)
   This is equivalent to the Java expression `new Integer("255")'.  You
can also write:
     (Int32:new "255")
   Kawa is smart enough to convert the Kawa string to a Java String.

   You can invoke non-static methods the same way.  In that case the
first argument is the receiver or `this' argument.
     (Int32:toString (Int32:new "00255"))
   This evaluates to the Java String `"255"'.

   As a shorthand, you can use the name of a Java class instead of a
namespace alias:
     (java.lang.Integer:toHexString 255)
     (java.lang.Object:toString some-value)
   If Kawa sees a qualified name with a prefix that is not defined _and_
that matches the name of an existing class, then Kawa will automaticaly
treat the prefix as a nickname for namespace uri like
`class:java.lang.Integer'.  Both conditions should be true at both
compile-time and run-time.  However, using an explicit
`define-namespace' is recommended.

   If you prefer, you can instead use the following functions.  (There
is also an older deprecated lower-level interface (*note Low-level
Method invocation::.)

 - 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
     identical, 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)
     or
          (let ((my-date :: <java.util.Date> (calculate-date))
                (cur-date :: <int> (get-cur-date)))
            (invoke 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)'.

