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



The Kawa Scheme system, by Per Bothner
**************************************

Kawa is a Scheme environment, written in Java, and that compiles Scheme
code into Java byte-codes.

This documents version 1.6.1, updated 11 March 1998.

See the summary of recent changes (http://www.cygnus.com/~bothner/kawa/News.txt).

The author of Kawa is Per Bothner <bothner@cygnus.com>.  It is a
re-write of Kawa 0.2, which was written by R. Alexander Milowski
<alex@copsol.com>.

The Kawa home page (which is currently just an on-line version of this
document) is `http://www.cygnus.com/~bothner/kawa.html'.
Copsol's Kawa home-page (http://www.copsol.com/sgmlimpl/tools/kawa/index.html) is not maintained by me and so may not be as current.

The Scheme repository (http://www.cs.indiana.edu/scheme-repository/home.html) has various useful information on Scheme, including a
pointer to an online copy of
R4RS (http://www-swiss.ai.mit.edu/~jaffer/r4rs_toc.html).

Javadoc generated
documentation of the Kawa classes (http://www.cygnus.com/~bothner/kawa/api/packages.html) is now available online.

For copyright information on the software and documentation, see *Note
License::.

This package has nothing to do with the
Kawa commercial Java IDE (http://www.tek-tools.com/kawa/).

The two packages `gnu.bytecode' (http:../gnu.bytecode/) and
`gnu.math' (http:../gnu.math/) are used by Kawa, and distributed with
it, but may be independently useful.

Features
********

Kawa is a full Scheme implementation.  It implements almost all of R5RS
(for exceptions *note Restrictions::.), plus some extensions.  By
default, symbols are case sensitive.

It is completely written in Java.  Scheme functions and files are
automatically compiled into Java byte-codes, providing reasonable
speed.  (However, Kawa is not an optimizing compiler, and does not
perform major transformations on the code.)

Kawa provides the usual read-eval-print loop, as well as batch modes.

Kawa is written in an object-oriented style.

Kawa implements most of the features of the expression language of
DSSSL, the Scheme-derived ISO-standard Document Style Semantics and
Specification Language for SGML.  Of the core expression language, the
only features missing are character properties, `external-procedure',
the time-relationed procedures, and character name escapes in string
literals.  Also, Kawa is not generally tail-recursive.  From the full
expression language, Kawa additionally is missing `format-number',
`format-number-list', and language objects.  Quantities, keyword
values, and the expanded `lambda' form (with optional and keyword
parameters) are supported.

Getting Kawa
************

The current sources release is in
`ftp://ftp.cygnus.com/pub/bothner/kawa-current.tar.gz'.

A ready-to-run `.zip' archive of the pre-compiled classes is in
`ftp://ftp.cygnus.com/pub/bothner/kawa-current-compiled.zip'.

A snapshot of the development tree is in
`ftp://ftp.cygnus.com/pub/bothner/kawa-newest.tar.gz'.

These are all in the Kawa ftp site (ftp://ftp.cygnus.com/pub/bothner),
which includes other versions and files, including a `.deb' Debian
package file of Kawa.

Building and installing Kawa
****************************

Before installing Kawa, you must have Java working on your system.

You can compile Kawa from the source distribution.  Alternatively, you
can install the pre-compiled binary distribution.

Getting and running Java
========================

You will need a working Java system.  The discussion below assumes you
are using the Java Developer's Kit (JDK) version 1.1.x from JavaSoft
(Sun).  (Kawa has also been reported to work with Kaffe, Symantec Cafe,
J++, and JDK 1.2beta.)  You can download free copies of JDK 1.1.x for
various platforms from
`http://java.sun.com/products/jdk/1.1/index.html/index.html'.

The program `java' is the Java interpreter.  The program `javac' is the
Java compiler, and is needed if you want to compile the source release
yourself.  Both programs must be in your `PATH'.

You also need to set `CLASSPATH' so it includes both the current
directory, and the standard Java library.  After you have installed
Kawa, the `CLASSPATH' needs to include wherever you installed Kawa.

If you have the JDK in directory `$JDK', and you are using a
Bourne-shell compatible shell (/bin/sh, ksh, bash, and some others) you
can set both variables thus:
     PATH=$JDK/bin:$PATH
     CLASSPATH=.:$JDK/lib/classes.zip
     export PATH CLASSPATH

Installing and using the binary distribution
============================================

The binary release includes only the binary compiled `.class' versions
of the same `.java' source files in the source release.  It does not
include any documentation, so you probably want the source release in
addition to the binary release.  The purpose of the binary release is
just to save you time and trouble of compiling the sources.

The binary release comes as a `.zip' archive `kawa-1.6.1-compiled.zip'.

You can unzip the archive, or you can use it as is.  Assuming the
latter, copy the archive to some suitable location, such as
`/usr/local/lib/kawa-compiled.zip'.

Then, before you can actually run Kawa, you need to set `CLASSPATH' so
it includes the Kawa archive.  On Unix, using a Bourne-style shell:
     CLASSPATH=/usr/local/lib/kawa-compiled.zip
     export CLASSPATH

On Windows95/WindowsNT, you need to set `classpath' in a DOS console.
For example:
     set classpath=\kawa\kawa-compiled.zip

Then to run Kawa do:
     java kawa.repl

Installing and using the source distribution
============================================

The Kawa release normally comes as a gzip-compressed tar file named
`kawa-1.6.1.tar.gz'.

In your build directory do:
     tar xzf kawa-1.6.1.tar.gz
     cd kawa-1.6.1

Then you must configure the sources.  This you can do the same way you
configure most other GNU software.  Normally you can just run the
configure script with no arguments:

     ./configure

This will specify that a later `make install' will install the compiled
`.class' files into `/usr/local/share/java'.  If you want them to be
installed someplace else, such as `$PREFIX/share/java', then specify
that when you run configure:
     ./configure --prefix $PREFIX

Thus you need to compile all the .java source files.  Just run make:
     make
This assume that `java' and `javac' are the java interpreter and
compiler, respectively.  If you are using the Kaffe free Java
interpreter, you need to instead say:
     make JAVA=kaffe

You can now test the system by running Kawa in place:
     java kawa.repl

or you can run the test suite:
     (cd testsuite;  make check)

or you can install the compiled files:
     make install

This will install your classes into `$PREFIX/share/java' (and its
sub-directories).  Here `$PREFIX' is the directory you specified to
configure with the `--prefix' option, or `/usr/local' if you did not
specify a `--prefix' option.

To use the installed files, you need to set `CLASSPATH' so that
`$PREFIX/share/java' is on the path:
     CLASSPATH=$PREFIX/share/java
     export CLASSPATH
This is done automatically if you use the `kawa' script.

I have not yet tried to build Kawa from source on Windows95, though I
understand others have done so.  (If you know how, let me know!)

How to start up and run Kawa
****************************

The easiest way to start up Kawa is to run the `kawa' script.  This
finds your java interpreter, and sets up `CLASSPATH' correctly.  If you
have installed Kawa such `$PREFIX/bin' is in your `$PATH', just do:
     kawa
However, `kawa' only works if you have a Unix-like environment.

To run Kawa manually, you must start a Java interpreter.  How you do
this depends on the Java interpreter.  For JavaSoft's JDK, you must
have the Java interpreter in your `PATH'.  You must also make sure that
the `kawa/repl.class' file, the rest of the Kawa packages, and the
standard Java packages can be found by searching CLASSPATH.  *Note
Running Java::.

Then you do:
     java kawa.repl

In either case, you will then get the `#|kawa:1|#' prompt, which means
you are in the Kawa read-eval-print-loop.  If you type a Scheme
expression, Kawa will evaluate it.  Kawa will then print the result (if
there is a non-"void" result).

Command-line arguments
======================

You can pass various flags to Kawa, for example:
     kawa -e '(display (+ 12 4))(newline)'
or:
     java kawa.repl -e '(display (+ 12 4))(newline)'
Either causes Kawa to print `16', and then exit.

At startup, Kawa executes an init file from the user's home directory.
The init file is named `.kawarc.scm' on Unix-like systems (those for
which the file separator is `'/''), and `kawarc.scm' on other systems.
This is done before the read-eval-print loop or before the first `-f'
or `-c' argument.  (It is not run for a `-e' command, to allow you to
set options to override the defaults.)

`-e EXPR'
     Kawa evaluates EXPR, which contains one or more Scheme expressions.
     Does not cause the `~/.kawarc.scm' init file to be run.

`-c EXPR'
     Same as `-e EXPR', except that it does cause the `~/.kawarc.scm'
     init file to be run.

`-f FILENAME'
     Kawa reads and evaluates expressions from the file named by
     FILENAME.  If FILENAME is `-', standard input is read (with no
     prompting).

`-s'
`--'
     The global variable `command-line-arguments' is set to the
     remaining arguments (if any), and an interactive read-eval-print
     loop is started.  This uses the same "console" as where you
     started up Kawa; use `-w' to get a new window.

`-w'
     Creates a new top-level window, and runs an interactive
     read-eval-print in the new window.  See *Note New-Window::.  Same
     as `-e (scheme-window #t)'.  You can specify multiple `-w'
     options, and also use `-s'.

`--version'
     Prints out the Kawa version number, and then exits.

The options `-C', `-d', `-T', `-P', and `--main' are used to compile a
Scheme file; see *Note Files compilation::.

If there are further command-line arguments after the options have been
processed, then the first remaining argument names a file that is read
and evaluated.  If there is no such argument, then Kawa enters an
interactive read-eval-print loop, but only if none of the `-c', `-e',
`-f', `-s', `-C', or `--' options were specified.

Running a Command Interpreter in a new Window
=============================================

An alternative interface runs the Java read-eval-print-loop inside a
new window. This is in some ways nicer.  One reason is that it provides
better editing.  You can also create new windows.  They can either have
different top-level environments or they can share environments.  To
try it, do:
     java kawa.repl -w

Exiting Kawa
============

Kawa normally keeps running as long as there is an active
read-eval-print loop still awaiting input or there is an unfinished
other computation (such as requested by a `-e' of `-f' option).

To close a read-eval-print-loop, you can type the special literal
`#!eof' at top level.  This is recognized as end-of-file.
Unfortunately, due to thread-related complications, just typing an
end-of-file character (normally ctrl/D until Unix), will not work.

If the read-eval-print-loop is in a new window, you can select `Close'
from the `File' menu.

To exit the entire Kawa session, call the `exit' procedure (with 0 or 1
integer arguments).

Features of R5RS not implemented
********************************

Kawa implements all the required and optional features of R5RS, with
the following exceptions.

The entire "numeric tower" is implemented.  However, some
transcendental function only work on reals.  Integral function do not
necessarily work on inexact (floating-point) integers.  (The whole idea
of "inexact integer" in R5RS seems rather pointless ...)

Also, call-with-current-continuation is only "upwards" (?).  I.e. once
a continuation has been exited, it cannot be invoked.  These restricted
continuations can be used to implement catch/throw (such as the
examples in R4RS), but not co-routines or backtracking.

Kawa does not do general tail-call elimination.  However, if the
compiler can prove that the procedure being called is the current
function, then the tail call will be replaced by a jump.  This means
the procedure must be defined using a letrec, not a define (because the
compiler does not know if someone might re-define a global definition),
and there must be no assignments (using `set!') to the procedure
binding.

The `define-syntax' primitive is provided, but has some bugs making it
not properly hygienic.  Neither `let-syntax' nor `letrec-syntax' are
implemented.

Extensions
**********

Multiple values
===============

The multiple-value feature will be in R5RS.

 - Function: values OBJECT ...
     Delivers all of its arguments to its continuation.

 - Function: call-with-values THUNK RECEIVER
     Call its THUNK argument with a continuation that, when passed some
     values, calls the RECEIVER procedure with those values as
     arguments.

Special named constants
=======================

 - Constant: #!optional
     Special self-evaluating literal used in lambda parameter lists
     before optional parameters.

 - Constant: #!rest
     Special self-evaluating literal used in lambda parameter lists
     before the rest parameter.

 - Constant: #!key
     Special self-evaluating literal used in lambda parameter lists
     before keyword parameters.

 - Constant: #!eof
     The end-of-file object.

     Note that if the Scheme reader sees this literal at top-level, it
     is returned literally.  This is indistinguishable from coming to
     the end of the input file.  If you do not want to end reading, but
     want the actual value of `#!eof', you should quote it.

 - Constant: #!void
     The void value.  Same as `(values)'.  If this is the value of an
     expression in a read-eval-print loop, nothing is printed.

 - Constant: #!null
     The Java `null' value.  This is not really a Scheme value, but is
     useful when interfacing to low-level Java code.

Keywords
========

Keywords are similar to symbols.  The main difference is that keywords
are self-evaluating and therefore do not need to be quoted in
expressions.  They are used mainly for specifying keyword arguments.

     KEYWORD = IDENTIFIER:

A keyword is a single token; therefore no whitespace is allowed between
the IDENTIFIER and the colon (which is not considered part of the name
of the keyword).

 - Function: keyword? OBJ
     Return `#t' if OBJ is a keyword, and otherwise returns `#f'.

 - Function: keyword->string KEYWORD
     Returns the name of KEYWORD as a string.  The name does not
     include the final `#\:'.

 - Function: string->keyword STRING
     Returns the keyword whose name is STRING.  (The STRING does not
     include a final `#\:'.)

Optional and keyword lambda parameters
======================================

Kawa borrows the extended formal argument list of DSSSL:

     LAMBDA-EXPRESSION = (lambda (FORMAL-ARGUMENTS) BODY)
You can of course also use the extended format in a `define':
     (define (NAME FORMAL-ARGUMENTS) BODY)

     FORMAL-ARGUMENTS =
     REQ-OPT-ARGS . REST-ARG OR:
     REQ-OPT-ARGS REST-KEY-ARGS

     REQ-OPT-ARGS = REQ-ARG* (#!optional OPT-ARG*)?
     REST-KEY-ARGS = (#!rest REST-ARG)? (#!key KEY-ARG*)?
     OPT-ARG = VARIABLE | (VARIABLE INITIALIZER)
     REQ-ARG = VARIABLE
     KEY-ARG = VARIABLE | (VARIABLE INITIALIZER)
     REST-ARG = VARIABLE

When the procedure is applied to a list of actual arguments, the formal
and actual arguments are processed from left to right as follows:

   * The REQ-ARGs are bound to actual arguments starting with the first
     actual argument.  It shall be an error if there are fewer actual
     arguments then there are REQ-ARGs.

   * Next the OPT-ARGs are bound to remaining actual arguemnts.  If
     there are fewer remaining actual arguments than there are
     OPT-ARGs, then the remaining VARIABLEs are bound to the
     corresponding INITIALIZER, if one was specified, and otherwise to
     `#f'.  The INITIALIZER is evaluated in an environment in which all
     the previous formal parameters have been bound.

   * If there is a REST-ARG, it is bound to a list of all the remaining
     actual arguments.  These remaining actual arguments are also
     eligible to be bound to keyword arguments.   If there is no
     REST-ARG and there are no KEY-ARGs, then it shall be an error if
     there are any remaining actual arguments.

   * If `#!key' was specified, then there shall be an even number of
     remaining actual arguments.  These are interpreted as a series of
     pairs, where the first member of each pair is a keyword specifying
     the argument name, and the second is the corresponding value.  It
     shall be an error if the first member of a pair is not a keyword.
     It shall be an error if the argument name is not the same as a
     variable in a KEY-ARGs, unless there is a REST-ARG.  If the same
     argument name occurs more than once in the list of actual
     arguments, then the first value is used.  If there is no actual
     argument for a particular KEY-ARG, then the variable is bound to
     the corresponding INITIALIZER, if one was specified, and otherwise
     to `#f'.  The INITIALIZER is evaluated in an environment in which
     all the previous formal parameters have been bound.

Logical Number Operations
=========================

These functions operate on the 2's complement binary representation of
an exact integer.

 - Function: logand I ...
     Returns the bit-wise logical "and" of the arguments.  If no
     argument is given, the result is -1.

 - Function: logior I ...
     Returns the bit-wise logical "(inclusive) or" of the arguments.
     If no argument is given, the result is 0.

 - Function: logxor I ...
     Returns the bit-wise logical "exclusive or" of the arguments.  If
     no argument is given, the result is 0.

 - Function: lognot I
     Returns the bit-wise logical inverse of the argument.

 - Function: logop OP X Y
     Perform one of the 16 bitwise operations of X and Y, depending on
     OP.

 - Function: bittest I J
     Returns true if the arguments have any bits in common.  Same as
     `(not (zero? (logand I J)))', but is more efficient.

 - Function: logbit? I POS
     Returns `#t' iff the bit numbered POS in I is one.

 - Function: arithmetic-shift I J
     Shifts I by J.  It is a "left" shift if `J>0', and a "right" shift
     if `J<0'.

     The result is equal to `(floor (* I (expt 2 J)))'.

 - Function: ash I J
     Alias for `arithmetic-shift'.

 - Function: logcount I
     Count the number of 1-bits in I, if it is non-negative.  If I is
     negative, count number of 0-bits.

 - Function: integer-length I
     Return number of bits needed to represent I in an unsigned field.
     Regardless of the sign of I, return one less than the number of
     bits needed for a field that can represent I as a two's complement
     integer.

 - Function: bit-extract N START END
     Return the integer formed from the (unsigned) bit-field starting
     at START and ending just before END.  Same as `(arithmetic-shift
     (bitand n (bitnot (arithmetic-shift -1 end))) (- start))'.

Records
=======

The Record package provides a facility for user to define their own
record data types.  A record type is implemented as Java Class object,
and 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.

     In Kawa, returns a newly-created `Class' object that extends the
     `Record' class.  Each record field is implemented as a public Java
     instance field.

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

     In Kawa, RTD may be any `Class' that has a public default
     constructor, as long as the FIELD-NAMES are public instance
     fields.  (The fields should have type `Object' - unless you know
     what you are doing!)

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

     In Kawa, the returned procedure checks if the argument is an
     instance of RTD or one of its sub-classes.

 - 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.  (In
     Kawa, the FIELD-NAME can be any public non-final Object field of
     the `Class' 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.  (In Kawa, the FIELD-NAME can be any
     public non-final Object field of the `Class' RTD.)

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

     In Kawa, this is true if OBJ is an instance of `kawa.lang.Record'.

 - 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.  In Kawa, RECORD may be
     any object, and the value returned is the class of the object.

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

Ports
=====

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

 - Function: set-input-port-line-number! PORT NUM
     Set line number of the current line of PORT to NUM.

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

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

Signalling and recovering from exceptions
=========================================

 - Function: catch KEY THUNK HANDLER
     Invoke THUNK in the dynamic context of HANDLER for exceptions
     matching KEY.  If thunk throws to the symbol KEY, then HANDLER is
     invoked this way:

          (handler key args ...)

     KEY may be a symbol.  The THUNK takes no arguments.  If THUNK
     returns normally, that is the return value of `catch'.

     Handler is invoked outside the scope of its own `catch'.  If
     HANDLER again throws to the same key, a new handler from further
     up the call chain is invoked.

     If the key is `#t', then a throw to *any* symbol will match this
     call to `catch'.

 - Function: throw KEY &rest ARGS ...
     Invoke the catch form matching KEY, passing ARGS to the HANDLER.

     If the key is a symbol it will match catches of the same symbol or
     of #t.

     If there is no handler at all, an error is signaled.

 - procedure: error MESSAGE ARGS ...
     Raise an error with key `misc-error' and a message constructed by
     displaying MSG and writing ARGS.  This normally prints a stack
     trace, and brings you back to the top level, or exits kawa if you
     are not running interactively.

 - Function: primitive-throw EXCEPTION
     Throws the EXCEPTION, which must be an instance of a sub-class of
     `<java.lang.Throwable>'.

 - Syntax: try-finally BODY HANDLER
     Evaluate BODY, and return its result.  However, before it returns,
     evaluate HANDLER.  Even if BODY returns abnormally (by throwing an
     exception), HANDLER is evaluated.

     (This is implemented just like Java's `try'-`finally'.)

 - Syntax: try-catch BODY HANDLER ...
     Evaluate BODY, in the conect of the given HANDLER-SPECs.  Each
     HANDLER has the form:
          VAR TYPE EXP ...
     If an exception is thrown in BODY, the first HANDLE-SPEC is
     selected such that the thrown exception is an instance of the
     HANDLER's TYPE. If no HANDLER is selected, the exception is
     propagated through the dynamic execution context until a matching
     HANDLER is found.  (If no matching HANDLER is found, then an error
     message is printed, and the computation terminated.)

     Once a HANDLER is selected, the VAR is bound to the thrown
     exception, and the EXP in the HANDLER are executed.  The result of
     the `try-catch' is the result of BODY if no exception is thrown,
     or the value of the last EXP in the selected HANDLER if an
     exception is thrown.

     (This is implemented just like Java's `try'-`catch'.)

 - Function: dynamic-wind IN-GUARD THUNK OUT-GUARD
     All three arguments must be 0-argument procedures.  First calls
     IN-GUARD, then THUNK, then OUT-GUARD.  The result of the
     expression is that of THUNK.  If THUNK is exited abnormally (by
     throwing an exception or invoking a continuation), OUT-GUARD is
     called.

     If the continuation of the dynamic-wind is re-entered (which is
     not yet possible in Kawa), the IN-GUARD is called again.

     This function will be in R5RS.

Eval and Environments
=====================

 - Function: eval EXPRESSION [ENVIRONMENT]
     `eval' evaluates EXPRESSION in the environment indicated by
     ENVIRONMENT.

     The default for ENVIRONMENT is the result of
     `(interaction-environment)'.

 - Function: null-environment
     This procedure returns an environment that contains no variable
     bindings, but contains (syntactic) bindings for all the syntactic
     keywords.

     The effect of assigning to a variable in this environment (such as
     `let') is undefined.

 - Function: scheme-report-environment VERSION
     The VERSION must be an exact non-negative inetger corresponding to
     a version of one of the RevisedVERSION Reports on Scheme.  The
     procedure returns an environment that contains exactly the set of
     bindings specified in the corresponding report.

     This implementation supports VERSION that is 4 or 5.

     The effect of assigning to a variable in this environment (such as
     `car') is undefined.

 - Function: interaction-environment
     This procedure return an environment that contains
     implementation-defined bindings, as well as top-level user
     bindings.

 - Function: environment-bound? ENVIRONMENT SYMBOL
     Return true `#t' if there is a binding for SYMBOL in ENVIRONMENT;
     otherwise returns `#f'.

 - Syntax: fluid-let ((VARIABLE INIT) ...) BODY ...
     Evaluate the INIT expressions.  Then modify the dynamic bindings
     for the VARIABLES to the values of the INIT expressions, and
     evaluate the BODY expressions.  Return the result of the last
     expression in BODY.  Before returning, restore the original
     bindings.  The temporary bindings are only visible in the current
     thread, and its descendent threads.

Quantities
==========

As a super-class of numbers, Kawa also provides quantities.  A
"quantity" is a product of a "unit" and a pure number.  The number part
can be an arbitrary complex number.  The unit is a product of integer
powers of base units, such as meter or second.

Kawa quantities are a generalization of the quantities in DSSSL, which
only has length-derived quantities.

The precise syntax of quantity literals may change, but some examples
are `10pt' (10 points), `5s' (5 seconds), and `4cm2' (4 square
centimeters).

 - Function: quantity? OBJECT
     True iff OBJECT is a quantity.  Note that all numbers are
     quantities, but not the other way round.

 - Function: quantity->number Q
     Returns the pure number part of the quantity Q, relative to
     primitive (base) units.  If Q is a number, returns Q.  If Q is a
     unit, yields the magitude of Q relative to base units.

 - Function: quantity->unit Q
     Returns the unit of the quantity Q.  If Q is a number, returns the
     empty unit.

 - Function: make-quantity X UNIT
     Returns the product of X (a pure number) and UNIT.  You can
     specify a string instead of UNIT, such as `"cm"' or `"s"'
     (seconds).

 - Syntax: define-unit UNIT-NAME EXPRESSION
     Define UNIT-NAME as a unit (that can be used in literals) equal to
     the quantity EXPRESSION.

Threads
=======

There is a very preliminary interface to create parallel threads.  The
interface is similar to the standard `delay'/`force', where a thread is
basically the same as a promise, except that evaluation may be in
parallel.

So far, little or no effort has been made into making Kawa thread-safe.
There are no per-thread bindings, and the current input and output
parts are global.  That needs to change.

 - Syntax: future EXPRESSION
     Creates a new thread that evaluates EXPRESSION.

 - Function: force THREAD
     The standard `force' function has generalized to also work on
     threads.  If waits for the thread's EXPRESSION to finish
     executing, and returns the result.

 - Function: sleep TIME
     Suspends the current thread for the specified time.  The TIME can
     be either a pure number (in secords), or a quantity whose unit is
     a time unit (such as `10s').

Standard Types
==============

Kawa has first-class types, that you can use in various ways.
Currently, these are mainly useful for interfacing with primitive Java
methods (such as `primitive-virtual-function', but they will be useful
for other purposes (such as declarating variables) later.

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/lang/PrimProcedure.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: <integer>
     The type of Scheme integers.

 - 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: <vector>
     The type of Scheme vectors.

 - Variable: <function>
     The type of Scheme procedures.

 - Variable: <input-port>
     The type of Scheme input ports.

 - Variable: <output-port>
     The type of Scheme output ports.

More will be added later.

In addition, any Java type can be named using this syntax.  For example
`<java.lang.StringBuffer[]>' represents an array of references to
`java.lang.StringBuffer' objects.

Processes
=========

 - Function: make-process COMMAND ENVP
     Creates a `<java.lang.Process>' object, using the specified
     COMMAND and ENVP.  The COMMAND is converted to an array of Java
     strings (that is an object that has type `<java.lang.String[]>'.
     It can be a Scheme vector or list (whose elements should be Java
     strings or Scheme strings);  a Java array of Java strings; or a
     Scheme string.  In the latter case, the command is converted using
     `command-parse'.  The ENVP is process environment;  it should be
     either a Java array of Java strings, or the special `#!null' value.

 - Function: system COMMAND
     Runs the specified COMMAND, and waits for it to finish.  Returns
     the return code from the command.  The return code is an integer,
     where 0 conventionally means successful completion.  The COMMAND
     can be any of the types handled by `make-process'.

 - Variable: command-parse
     The value of this variable should be a one-argument procedure.  It
     is used to convert a command from a Scheme string to a Java array
     of the constituent "words".  The default binding, on Unix-like
     systems, returns a new command to invoke `"/bin/sh" "-c"'
     concatenated with the command string; on non-Unix-systems, it is
     bound to `tokenize-string-to-string-array'.

 - Function: tokenize-string-to-string-array COMMAND
     Uses a `java.util.StringTokenizer' to parse the COMMAND string
     into an array of words.  This splits the COMMAND using spaces to
     delimit words; there is no special processing for quotes or other
     special characters.  (This is the same as what
     `java.lang.Runtime.exec(String)' does.)

Miscellaneous
=============

 - Function: scheme-implementation-version
     Returns the Kawa version number as a string.

 - Function: gentemp
     Returns a new (interned) symbol each time it is called.  The
     symbol names are implementation-dependent.

 - Syntax: defmacro NAME LAMBDA-LIST FORM ...
     Defines an old-style macro a la Common Lisp, and installs `(lambda
     LAMBDA-LIST FORM ...)'  as the expansion function for NAME.  When
     the translator sees an application of NAME, the expansion function
     is called with the rest of the application as the actual
     arguments.  The resulting object must be a Scheme source form that
     is futher processed (it may be repeatedly macro-expanded).

     If you define a macro with `defmacro', you (currently) cannot use
     the macro in the same compilation as the definition.  This
     restriction does not apply to macros defined by `define-syntax'.

 - Variable: command-line-arguments
     Any command-line arguments (following flags processed by Kawa
     itself) are assigned to the global variable
     `command-line-arguments', which is a vector of strings.

 - Variable: home-directory
     A string containing the home directory of the user.

 - Function: exit [CODE]
     Exits the Kawa interpreter, and ends the Java session.  The
     integer value CODE is returned to the operating system.  If CODE
     is not specified, zero is returned, indicating normal (non-error)
     termination.

 - Function: scheme-window [SHARED]
     Create a read-eval-print-loop in a new top-level window.  If
     SHARED is true, it uses the same environment as the current
     `(interaction-environment)';  if not (the default), a new
     top-level environment is created.

     You can create multiple top-level window that can co-exist.  They
     run in separate threads.

 - Function: apply PROC [ARG1 ...] ARGS
     ARGS must be a sequence (list, vector, or string) or a primitive
     Java array.  (This is an extension over standard Scheme, which
     requires that ARGS be a list.)  Calls the PROC (which must be a
     procedure), using as arguments the ARG1... values plus all the
     elements of ARGS.

 - Syntax: constant-fold PROC ARG1 ...
     Same as `(PROC ARG1 ...)', unless PROC and all the following
     arguments are compile-time constants.  (That is:  They are either
     constant, or symbols that have a global binding and no lexical
     binding.)  In that case, PROC is applied to the arguments at
     compile-time, and the result replaces the `constant-fold' form.
     If the application raises an exception, a compile-time error is
     reported.  For example:
          (constant-fold vector 'a 'b 'c)
     is equivalent to `(quote #(a b c))', assuming `vector' has not
     been re-bound.

 - Syntax: when CONDITION FORM...
     If CONDITION is true, evaluate each FORM in order, returning the
     value of the last one.

 - Syntax: unless CONDITION FORM...
     If CONDITION is false, evaluate each FORM in order, returning the
     value of the last one.

 - Function: vector-append ARG...
     Creates a new vector, containing the elements from all the ARGs
     appended together.   Each ARG may be a vector or a list.

 - Function: instance? VALUE TYPE
     Returns `#t' iff VALUE is an instance of type TYPE.  (Undefined if
     TYPE is a primitive type, such as `<int>'.)

 - Function: as TYPE VALUE
     Converts or coerces VALUE to a value of type TYPE.  Throws an
     exception if that cannot be done.  Not supported for TYPE to be a
     primitive type such as `<int>'.

Compiling Scheme code to byte-codes
***********************************

All Scheme functions and source files are invisibly compiled into
internal Java byte-codes.  A traditional evaluator is only used for
top-level directly entered expressions *outside* a lambda.  (It would
have been simpler to also byte-compile top-level expressions by
surrounding them by a dummy lambda.  However, this would create a new
Class object in the Java VM for every top-level expression.  This is
undesirable unless you have a VM that can garbage collect Class
objects.)

To save speed when loading large Scheme source files, you probably want
to pre-compile them and save them on your local disk.  There are two
ways to do this.

You can compile a Scheme source file to a single archive file.  You do
this using the `compile-file' function.  The result is a single file
that you can move around and `load' just like the `.scm' source file.
You just specify the name of the archive file to the `load' procedure.
Currently, the archive is a "zip" archive and has extension ".zip"; a
future release will probably use "Java Archive" (jar) files.  The
advantage of compiling to an archive is that it is simple and
transparent.  A minor disadvantage is that it causes the Java
"verifier" to be run when functions are loaded from it, which takes a
little extra time.

Alternatively, you can compile a Scheme source file to a collection of
`.class' files.  You then use the standard Java class loading mechanism
to load the code.  The Java "verifier" does not need to get run, which
makes loading a little faster.  The compiled class files do have to be
installed be installed somewhere in the `CLASSPATH'.

Compiling Scheme to an archive file
===================================

To byte-compile a file `foo.scm' do:
     (compile-file "foo.scm" "foo")

This will create `foo.zip', which contains byte-compiled "j-code" that
implements `foo.scm'.

You can later do:
     (load "foo")

This will load `foo.zip', which should have the same effect as loading
`foo.scm', except you will get the byte-compiled versions.

Compiling Scheme to a set of .class files
=========================================

Invoking `kawa' (or `java kawa.repl') with the `-C' flag will compile a
`.scm' source file into one or more `.class' files.

You run it as follows:
     kawa [-d OUTDIRECTORY] [-P PREFIX] [-T TOPNAME] [--main] -C INFILE

Note the `-C' must come last, because `Kawa' processes the arguments
and options in order,

Here:
`-C INFILE'
     The Scheme source file we want to compile.

`-d OUTDIRECTORY'
     The directory under which the resulting `.class' files will be.
     The default is the current directory.

`-P PREFIX'
     A string to prepend to the generated class names.  The default is
     the empty string.

`-T TOPNAME'
     The name of the "top" class - i.e. the one that contains the code
     for the top-level expressions and definitions.  The default is
     generated from the INFILE and PREFIX.

`--main'
     Generate a `main' method so that the resulting "top" class can be
     used as a stand-alone application. *Note Application compilation::.

When you actually want to load the classes, the OUTDIRECTORY must be in
your `CLASSPATH'.  You can use the standard `load' function to load the
code, by specifying the top-level class, either as a file name
(relative to OUTDIRECTORY) or a class name.  E.g. if you did:
     kawa -d /usr/local/share/java -P my.lib. -T foo -C foosrc.scm
you can use either:
     (load "my.lib.foo")
or:
     (load "my/lib/foo.class")

If you are compiling a Scheme source file (say `foosrc.scm') that uses
macros defined in some other file (say `macs.scm'), you need to make
sure the definitions are visible to the compiler.  One way to do that
is with the `-f':
     kawa -f macs.scm -C foosrc.scm

Compiling Scheme to a standalone application
============================================

A Java application is a Java class with a special method (whose name is
`main').  The application can be invoked directly by naming it in the
Java command.  If you want to generate an application from a Scheme
program, create a Scheme source file with the definitions you need, plus
the top-level actions that you want the application to execute.  You
can compile in the regular way decribed in the previous section, but add
the `--main' option.  For example, assuming your Scheme file is
`MyProgram.scm':
     kawa --main -C MyProgram.scm
This will create a `MyProgram.class' which you can either `load' (as
decribed in the previous section), or invoke as an application:
     java MyProgram [ARGS]
Your Scheme program can access the command-line arguments ARGS by using
the global variable `command-line-arguments'.

The Scheme-Java interface
*************************

Kawa has extensive features so you can work with Java objects and call
Java methods,

Scheme types in Java
====================

All Scheme values are implemented by sub-classes of `java.lang.Object'.

Scheme symbols are implemented using `java.lang.String'.  (Don't be
confused by the fact the Scheme sybols are represented using Java
Strings, while Scheme strings are represented by `kawa.lang.Scheme'.
It is just that the semantics of Java strings match Scheme symbols, but
do not match mutable Scheme strings.)  Interned symbols are presented
as interned Strings.  (Note that with JDK 1.1 string literals are
automatically interned.)

Scheme integers are implemented by `kawa.math.IntNum'.  Use the make
static function to create a new IntNum from an int or a long.  Use the
intValue or longValue methods to get the int or long value of an IntNum.

A Scheme "flonum" is implemented by `kawa.math.DFloNum'.

A Scheme pair is implemented by `kawa.lang.Pair'.

A Scheme vector is implemented by `kawa.lang.Vector'.

Scheme characters are implemented using `kawa.lang.Char'.

Scheme strings are implemented using `kawa.lang.FString'.

Scheme procedures are all sub-classes of `kawa.lang.Procedure'.
Normally each function (lambda expression) in the source code is
compiled to a separate sub-class of `Procedure'.  The "action" of a
`Procedure' is invoked by using one of the `apply*' methods:  `apply0',
`apply1', `apply2', `apply3', `apply4', or `applyN'.  Various sub-class
of `Procedure' provide defaults for the various `apply*' methods.  For
example, a `Procedure2' is used by 2-argument procedures.  The
`Procedure2' class provides implementations of all the `apply*' methods
*except* `apply2', which must be provided by any class that extends
`Procedure2'.

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

Kawa provides a simple yet powerful "Foreign Function Interface", which
allows you to call any (virtual or static) Java method as if it were a
Scheme procedure.

These primitives require you to specify the parameter and return types.
Type specifications are currently required to be string literals or one
of the standard types (*note Standard Types::.).  A type specifier can
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.  The specification `<String>' is an
exception: It causes the `toString' method of the actual argument to be
invoked.

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.

 - Syntax: primitive-constructor CLASS (ARGTYPE ...)
     Returns a new anonymous procedure, which when called will create a
     new object of the specified class, and will then call the
     constructor matching the specified argument types.

 - Syntax: primitive-virtual-method CLASS METHOD RTYPE (ARGTYPE ...)
     Returns a new anonymous procedure, which when called will invoke
     the instance method whose name is the string METHOD in the class
     whose name is CLASS.

 - Syntax: primitive-static-method CLASS METHOD RTYPE (ARGTYPE ...)
     Returns a new anonymous procedure, which when called will invoke
     the static method whose name is the string METHOD in the class
     whose name is CLASS.

 - Syntax: primitive-interface-method INTERFACE METHOD RTYPE (ARGTYPE
          ...)
     Returns a new anonymous procedure, which when called will invoke
     the matching method from the interface whose name is INTERFACE.

The macros return procedure values, just like `lambda'.  If the macros
are used directly as the procedure of a procedure call, then kawa can
inline the correct bytecodes to call the specified methods.  (Note also
that neither macro checks that there really is a method that matches
the specification.)  Otherwise, the Java reflection facility is used.

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

Low-level Operations on Object Fields
=====================================

The following macros evaluate to procedures that can be used to access
or change the fields of objects or static fields.  The compiler can
inline each to a single bytecode instruction (not counting type
conversion).

 - Syntax: primitive-get-field CLASS FNAME FTYPE
     Use this to access a field named FNAME having type TYPE in class
     CLASS.  Evaluates to a new one-argument procedure, whose argument
     is a reference to an object of the specified CLASS.  Calling that
     procedure returns the value of the specified field.

 - Syntax: primitive-set-field CLASS FNAME FTYPE
     Use this to change a field named FNAME having type TYPE in class
     CLASS.  Evaluates to a new two-argument procedure, whose first
     argument is a reference to an object of the specified CLASS, and
     the second argument is the new value.  Calling that procedure sets
     the field to the specified value.  (This macro's name does not end
     in a `!', because it does not actually set the field.  Rather, it
     returns a function for setting the field.)

 - Syntax: primitive-get-static CLASS FNAME FTYPE
     Like `primitive-get-field', but used to access static fields.
     Returns a zero-argument function, which when called returns the
     value of the static field.

 - Syntax: primitive-set-static CLASS FNAME FTYPE
     Like `primitive-set-field', but used to modify static fields.
     Returns a one-argument function, which when called sets the value
     of the static field to the argument.

Low-level Operations on Java Arrays
===================================

The following macros evaluate to procedures that can be used to
manipulate primitive Java array objects.  The compiler can inline each
to a single bytecode instruction (not counting type conversion).

 - Syntax: primitive-array-new ELEMENT-TYPE
     Evaluates to a one-argument procedure.  Applying the resulting
     procedure to an integer count allocates a new Java array of the
     specified length, and whose elements have type ELEMENT-TYPE.

 - Syntax: primitive-array-set ELEMENT-TYPE
     Evaluates to a three-argument procedure.  The first argument of
     the resulting procedure must be an array whose elements have type
     ELEMENT-TYPE;  the second argument is an index;  and the third
     argument is a value (coercible to ELEMENT-TYPE) which replaces the
     value specified by the index in the given array.

 - Syntax: primitive-array-set ELEMENT-TYPE
     Evaluates to a two-argument procedure.  The first argument of the
     resulting procedure must be an array whose elements have type
     ELEMENT-TYPE;  the second argument is an index.  Applying the
     procedure returns the element at the specified index.

 - Syntax: primitive-array-new ELEMENT-TYPE
     Evaluates to a one-argument procedure.  The argument of the
     resulting procedure must be an array whose elements have type
     ELEMENT-TYPE.  Applying the procedure returns the length of the
     array.

Loading a ModuleBody
====================

The "top" class created by `kawa -C' (*note Files compilation::.)
extends the `ModuleBody' class.  It is actually fairly easy to write a
`ModuleBody' by hand in Java, and you can then use the Scheme `load'
procedure to cause arbitrary actions.  Here is an example.  *(Note that
the details are subject to change!)*

     package MyDev;
     import kawa.lang.*;
     class MyDevFunc extends Procedure2
     {
       public Object apply2 (Object arg1, Object arg2)
       {
         ... stuff to control my device ...;
       }
     }
     
     public class MyDevice extends ModuleBody
     {
       public Object run (Environment env)
         throws WrongArguments, WrongType, GenericError, UnboundSymbol
       {
         ... initialize my device here ...;
     
         // Declare (handle-my-device x y) to call MyDevFunc.apply2 (x, y):
         env.define ("handle-my-device", new MyDevFunc ());
     
         // Return the void value (i.e. no value).
         return Interpreter.voidObject;
       }
     }

If this text is in the file `MyDev/MyDevice.java', and you compile it
with `javac', you will get `MyDev/MyDevice.class' and
`MyDev/MyDevFunc.class'.  Assuming the current directory is in your
`CLASSPATH', you can now do the following in Kawa:
     (load "MyDev/MyDevice.class")
or:
     (load "MyDev.MyDevice")

This will cause the actions in `MyDevice.run' to be executed.  The
current environment is passed in as the parameter `env'.  One of those
actions is to define the procedure `handle-my-device'.

Evaluating Scheme expressions from Java
=======================================

The following methods are recommended if you need to evaluate a Scheme
expression from a Java method.  (Some details (such as the `throws'
lists) may change.)

 - Static method: Object Scheme.eval (InPort PORT, Environment ENV)
     Read expressions from PORT, and evaluate them in the ENV
     environment, until end-of-file is reached.  Return the value of
     the last expression, or `Interpreter.voidObject' if there is no
     expression.

 - Static method: Object Scheme.eval (String STRING, Environment ENV)
     Read expressions from STRING, and evaluate them in the ENV
     environment, until the end of the string is reached.  Return the
     value of the last expression, or `Interpreter.voidObject' if there
     is no expression.

 - Static method: Object Scheme.eval (Object SEXPR, Environment ENV)
     The SEXPR is an S-expression (as may be returned by `read').
     Evaluate it in the ENV environment, and return the result.

For the `Environment' in most cases you could use
`Environment.current()'.

Reporting Bugs and the Kawa Mailing List
****************************************

If you have a problem installing or using Kawa, send mail to
`kawa@cygnus.com'

This mailing list is used for reporting bugs, patches, discussing
changes to Kawa, and announcing snapshots.  If you wish to subscribe
(or later unsubscribe), send a request to `kawa-request@cygnus.com'.

Messages to the mailing list are now archived (http://www.cygnus.com/ml/kawa/).

License
*******

This is the license for the Kawa software:

Note that the Kawa distribution includes two packages
gnu.bytecode (http:../gnu.bytecode/) and gnu.math (http:../gnu.math/)
which have different terms than Kawa itself (but which impose no
restrictions as long as you do not modify those two packages).

In general, If the license of Kawa or asociated packages causes
difficulties, let me know.

This software is copyrighted by Per Bothner, Cygnus Support, R.
Alexander Milowski, Copernican Solutions Incorporated, and other
parties.  The following terms apply to all files associated with the
software unless explicitly disclaimed in individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose,
provided that existing copyright notices are retained in all copies and
that this notice is included verbatim in any distributions. No written
agreement, license, or royalty fee is required for any of the
authorized uses.  Modifications to this software may be copyrighted by
their authors and need not follow the licensing terms described here,
provided that the new terms are clearly indicated on the first page of
each file where they apply.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

Here is the license for this manual:

Copyright (C) 1996, 1997 Per Bothner
Parts of this manual were derived from the SLIB manual, copyright (C)
1993, 1994 Todd R. Eigenschink and Aubrey Jaffer.
Parts of this manual were derived from ISO/EIC 10179:1996(E) (Document
Style and Specifical Language) - unknown copyright.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation
approved by the author.

