This is kawa.info, produced by makeinfo version 6.6 from kawa.texi.

START-INFO-DIR-ENTRY
* kawa: (kawa).         The Kawa Scheme language
END-INFO-DIR-ENTRY


File: kawa.info,  Node: Unicode,  Next: Regular expressions,  Prev: String literals,  Up: Characters and text

13.5 Unicode character classes and conversions
==============================================

Some of the procedures that operate on characters or strings ignore the
difference between upper case and lower case.  These procedures have
‘-ci’ (for “case insensitive”) embedded in their names.

13.5.1 Characters
-----------------

 -- Procedure: char-upcase CHAR
 -- Procedure: char-downcase CHAR
 -- Procedure: char-titlecase CHAR
 -- Procedure: char-foldcase CHAR
     These procedures take a character argument and return a character
     result.

     If the argument is an upper–case or title–case character, and if
     there is a single character that is its lower–case form, then
     ‘char-downcase’ returns that character.

     If the argument is a lower–case or title–case character, and there
     is a single character that is its upper–case form, then
     ‘char-upcase’ returns that character.

     If the argument is a lower–case or upper–case character, and there
     is a single character that is its title–case form, then
     ‘char-titlecase’ returns that character.

     If the argument is not a title–case character and there is no
     single character that is its title–case form, then ‘char-titlecase’
     returns the upper–case form of the argument.

     Finally, if the character has a case–folded character, then
     ‘char-foldcase’ returns that character.  Otherwise the character
     returned is the same as the argument.

     For Turkic characters ‘#\x130’ and ‘#\x131’, ‘char-foldcase’
     behaves as the identity function; otherwise ‘char-foldcase’ is the
     same as ‘char-downcase’ composed with ‘char-upcase’.

          (char-upcase #\i)               ⇒  #\I
          (char-downcase #\i)             ⇒  #\i
          (char-titlecase #\i)            ⇒  #\I
          (char-foldcase #\i)             ⇒  #\i

          (char-upcase #\ß)               ⇒  #\ß
          (char-downcase #\ß)             ⇒  #\ß
          (char-titlecase #\ß)            ⇒  #\ß
          (char-foldcase #\ß)             ⇒  #\ß

          (char-upcase #\Σ)               ⇒  #\Σ
          (char-downcase #\Σ)             ⇒  #\σ
          (char-titlecase #\Σ)            ⇒  #\Σ
          (char-foldcase #\Σ)             ⇒  #\σ

          (char-upcase #\ς)               ⇒  #\Σ
          (char-downcase #\ς)             ⇒  #\ς
          (char-titlecase #\ς)            ⇒  #\Σ
          (char-foldcase #\ς)             ⇒  #\σ

          _Note:_ ‘char-titlecase’ does not always return a title–case
          character.

          _Note:_ These procedures are consistent with Unicode’s
          locale–independent mappings from scalar values to scalar
          values for upcase, downcase, titlecase, and case–folding
          operations.  These mappings can be extracted from
          ‘UnicodeData.txt’ and ‘CaseFolding.txt’ from the Unicode
          Consortium, ignoring Turkic mappings in the latter.

          Note that these character–based procedures are an incomplete
          approximation to case conversion, even ignoring the user’s
          locale.  In general, case mappings require the context of a
          string, both in arguments and in result.  The ‘string-upcase’,
          ‘string-downcase’, ‘string-titlecase’, and ‘string-foldcase’
          procedures perform more general case conversion.

 -- Procedure: char-ci=? CHAR1 CHAR2 CHAR3 ...
 -- Procedure: char-ci<? CHAR1 CHAR2 CHAR3 ...
 -- Procedure: char-ci>? CHAR1 CHAR2 CHAR3 ...
 -- Procedure: char-ci<=? CHAR1 CHAR2 CHAR3 ...
 -- Procedure: char-ci>=? CHAR1 CHAR2 CHAR3 ...
     These procedures are similar to ‘char=?’, etc., but operate on the
     case–folded versions of the characters.

          (char-ci<? #\z #\Z)             ⇒ #f
          (char-ci=? #\z #\Z)             ⇒ #f
          (char-ci=? #\ς #\σ)             ⇒ #t

 -- Procedure: char-alphabetic? CHAR
 -- Procedure: char-numeric? CHAR
 -- Procedure: char-whitespace? CHAR
 -- Procedure: char-upper-case? CHAR
 -- Procedure: char-lower-case? CHAR
 -- Procedure: char-title-case? CHAR
     These procedures return ‘#t’ if their arguments are alphabetic,
     numeric, whitespace, upper–case, lower–case, or title–case
     characters, respectively; otherwise they return ‘#f’.

     A character is alphabetic if it has the Unicode “Alphabetic”
     property.  A character is numeric if it has the Unicode “Numeric”
     property.  A character is whitespace if has the Unicode
     “White_Space” property.  A character is upper case if it has the
     Unicode “Uppercase” property, lower case if it has the “Lowercase”
     property, and title case if it is in the Lt general category.

          (char-alphabetic? #\a)          ⇒  #t
          (char-numeric? #\1)             ⇒  #t
          (char-whitespace? #\space)      ⇒  #t
          (char-whitespace? #\x00A0)      ⇒  #t
          (char-upper-case? #\Σ)          ⇒  #t
          (char-lower-case? #\σ)          ⇒  #t
          (char-lower-case? #\x00AA)      ⇒  #t
          (char-title-case? #\I)          ⇒  #f
          (char-title-case? #\x01C5)      ⇒  #t

 -- Procedure: char-general-category CHAR
     Return a symbol representing the Unicode general category of CHAR,
     one of ‘Lu’, ‘Ll’, ‘Lt’, ‘Lm’, ‘Lo’, ‘Mn’, ‘Mc’, ‘Me’, ‘Nd’, ‘Nl’,
     ‘No’, ‘Ps’, ‘Pe’, ‘Pi’, ‘Pf’, ‘Pd’, ‘Pc’, ‘Po’, ‘Sc’, ‘Sm’, ‘Sk’,
     ‘So’, ‘Zs’, ‘Zp’, ‘Zl’, ‘Cc’, ‘Cf’, ‘Cs’, ‘Co’, or ‘Cn’.

          (char-general-category #\a)         ⇒ Ll
          (char-general-category #\space)     ⇒ Zs
          (char-general-category #\x10FFFF)   ⇒ Cn

13.5.2 Deprecated in-place case modification
--------------------------------------------

The following functions are deprecated; they really don’t and cannot do
the right thing, because in some languages upper and lower case can use
different number of characters.

 -- Procedure: string-upcase! str
     _Deprecated:_ Destructively modify STR, replacing the letters by
     their upper-case equivalents.

 -- Procedure: string-downcase! str
     _Deprecated:_ Destructively modify STR, replacing the letters by
     their upper-lower equivalents.

 -- Procedure: string-capitalize! str
     _Deprecated:_ Destructively modify STR, such that the letters that
     start a new word are replaced by their title-case equivalents,
     while non-initial letters are replaced by their lower-case
     equivalents.


File: kawa.info,  Node: Regular expressions,  Prev: Unicode,  Up: Characters and text

13.6 Regular expressions
========================

Kawa provides “regular expressions”, which is a convenient mechanism for
matching a string against a “pattern” and maybe replacing matching
parts.

   A regexp is a string that describes a pattern.  A regexp matcher
tries to match this pattern against (a portion of) another string, which
we will call the text string.  The text string is treated as raw text
and not as a pattern.

   Most of the characters in a regexp pattern are meant to match
occurrences of themselves in the text string.  Thus, the pattern “‘abc’”
matches a string that contains the characters “‘a’”, “‘b’”, “‘c’” in
succession.

   In the regexp pattern, some characters act as “metacharacters”, and
some character sequences act as “metasequences”.  That is, they specify
something other than their literal selves.  For example, in the pattern
“‘a.c’”, the characters “‘a’” and “‘c’” do stand for themselves but the
metacharacter “‘.’” can match any character (other than newline).
Therefore, the pattern “‘a.c’” matches an “‘a’”, followed by any
character, followed by a “‘c’”.

   If we needed to match the character “‘.’” itself, we “escape” it, ie,
precede it with a backslash “‘\’”.  The character sequence “‘\.’” is
thus a metasequence, since it doesn’t match itself but rather just
“‘.’”.  So, to match “‘a’” followed by a literal “‘.’” followed by “‘c’”
we use the regexp pattern “‘a\.c’”.  To write this as a Scheme string
literal, you need to quote the backslash, so you need to write
‘"a\\.c"’.  Kawa also allows the literal syntax ‘#/a\.c/’, which avoids
the need to double the backslashes.

   You can choose between two similar styles of regular expressions.
The two differ slightly in terms of which characters act as
metacharacters, and what those metacharacters mean:
   • Functions starting with ‘regex-’ are implemented using the
     ‘java.util.regex’ package.  This is likely to be more efficient,
     has better Unicode support and some other minor extra features, and
     literal syntax ‘#/a\.c/’ mentioned above.
   • Functions starting with ‘pregexp-’ are implemented in pure Scheme
     using Dorai Sitaram’s “Portable Regular Expressions for Scheme”
     library.  These will be portable to more Scheme implementations,
     including BRL, and is available on older Java versions.

13.6.1 Java regular expressions
-------------------------------

The syntax for regular expressions is documented here
(http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html).

 -- Type: regex
     A compiled regular expression, implemented as
     ‘java.util.regex.Pattern’.

 -- Constructor: regex arg
     Given a regular expression pattern (as a string), compiles it to a
     ‘regex’ object.

          (regex "a\\.c")
     This compiles into a pattern that matches an “‘a’”, followed by any
     character, followed by a “‘c’”.

   The Scheme reader recognizes “‘#/’” as the start of a regular
expression “pattern literal”, which ends with the next un-escaped “‘/’”.
This has the big advantage that you don’t need to double the
backslashes:
     #/a\.c/
   This is equivalent to ‘(regex "a\\.c")’, except it is compiled at
read-time.  If you need a literal “‘/’” in a pattern, just escape it
with a backslash: “‘#/a\/c/’” matches a “‘a’”, followed by a “‘/’”,
followed by a “‘c’”.

   You can add single-letter _modifiers_ following the pattern literal.
The following modifiers are allowed:
‘i’
     The modifier “‘i’” cause the matching to ignore case.  For example
     the following pattern matches “‘a’” or “‘A’”.
          #/a/i
‘m’
     Enables “metaline” mode.  Normally metacharacters “‘^’” and “‘$’’
     match at the start end end of the entire input string.  In metaline
     mode “‘^’” and “‘$’” also match just before or after a line
     terminator.

     Multiline mode can also be enabled by the metasequence “‘(?m)’”.
‘s’
     Enable “singleline” (aka “dot-all”) mode.  In this mode the
     matacharacter “‘.’ matches any character, including a line breaks.
     This mode be enabled by the metasequence “‘(?s)’”.

   The following functions accept a regex either as a pattern string or
a compiled ‘regex’ pattern.  I.e.  the following are all equivalent:
     (regex-match "b\\.c" "ab.cd")
     (regex-match #/b\.c/ "ab.cd")
     (regex-match (regex "b\\.c") "ab.cd")
     (regex-match (java.util.regex.Pattern:compile "b\\.c") "ab.cd")
   These all evaluate to the list ‘("b.c")’.

   The following functions must be imported by doing one of:
     (require 'regex) ;; or
     (import (kawa regex))

 -- Procedure: regex-match-positions regex string [start [end]]

     The procedure ‘regex‑match‑position’ takes pattern and a text
     STRING, and returns a match if the regex matches (some part of) the
     text string.

     Returns ‘#f’ if the regexp did not match the string; and a list of
     index pairs if it did match.
          (regex-match-positions "brain" "bird") ⇒ #f
          (regex-match-positions "needle" "hay needle stack")
            ⇒ ((4 . 10))

     In the second example, the integers 4 and 10 identify the substring
     that was matched.  4 is the starting (inclusive) index and 10 the
     ending (exclusive) index of the matching substring.

          (substring "hay needle stack" 4 10) ⇒ "needle"

     In this case the return list contains only one index pair, and that
     pair represents the entire substring matched by the regexp.  When
     we discuss subpatterns later, we will see how a single match
     operation can yield a list of submatches.

     ‘regex‑match‑positions’ takes optional third and fourth arguments
     that specify the indices of the text string within which the
     matching should take place.

          (regex-match-positions "needle"
            "his hay needle stack -- my hay needle stack -- her hay needle stack"
            24 43)
            ⇒ ((31 . 37))

     Note that the returned indices are still reckoned relative to the
     full text string.

 -- Procedure: regex-match regex string [start [end]]
     The procedure ‘regex‑match’ is called like ‘regex‑match‑positions’
     but instead of returning index pairs it returns the matching
     substrings:
          (regex-match "brain" "bird") ⇒ #f
          (regex-match "needle" "hay needle stack")
            ⇒ ("needle")

     ‘regex‑match’ also takes optional third and fourth arguments, with
     the same meaning as does ‘regex‑match‑positions’.

 -- Procedure: regex-split regex string
     Takes two arguments, a REGEX pattern and a text STRING, and returns
     a list of substrings of the text string, where the pattern
     identifies the delimiter separating the substrings.
          (regex-split ":" "/bin:/usr/bin:/usr/bin/X11:/usr/local/bin")
            ⇒ ("/bin" "/usr/bin" "/usr/bin/X11" "/usr/local/bin")

          (regex-split " " "pea soup")
            ⇒ ("pea" "soup")

     If the first argument can match an empty string, then the list of
     all the single-character substrings is returned, plus we get a
     empty strings at each end.

          (regex-split "" "smithereens")
            ⇒ ("" "s" "m" "i" "t" "h" "e" "r" "e" "e" "n" "s" "")

     (Note: This behavior is different from ‘pregexp-split’.)

     To identify one-or-more spaces as the delimiter, take care to use
     the regexp “‘ +’”, not “‘ *’”.
          (regex-split " +" "split pea     soup")
            ⇒ ("split" "pea" "soup")
          (regex-split " *" "split pea     soup")
            ⇒ ("" "s" "p" "l" "i" "t" "" "p" "e" "a" "" "s" "o" "u" "p" "")

 -- Procedure: regex‑replace regex string replacement
     Replaces the matched portion of the text STRING by another a
     REPLACDEMENT string.
          (regex-replace "te" "liberte" "ty")
            ⇒ "liberty"

     Submatches can be used in the replacement string argument.  The
     replacement string can use “‘$N’” as a “backreference” to refer
     back to the Nth submatch, ie, the substring that matched the Nth
     subpattern.  “‘$0’” refers to the entire match.
          (regex-replace #/_(.+?)_/
                         "the _nina_, the _pinta_, and the _santa maria_"
          		"*$1*"))
            ⇒ "the *nina*, the _pinta_, and the _santa maria_"

 -- Procedure: regex‑replace* regex string replacement
     Replaces all matches in the text STRING by the REPLACEMENT string:
          (regex-replace* "te" "liberte egalite fraternite" "ty")
            ⇒ "liberty egality fratyrnity"
          (regex-replace* #/_(.+?)_/
                          "the _nina_, the _pinta_, and the _santa maria_"
                          "*$1*")
            ⇒ "the *nina*, the *pinta*, and the *santa maria*"

 -- Procedure: regex-quote pattern
     Takes an arbitrary string and returns a pattern string that
     precisely matches it.  In particular, characters in the input
     string that could serve as regex metacharacters are escaped as
     needed.

          (regex-quote "cons")
            ⇒ "\Qcons\E"
     ‘regex‑quote’ is useful when building a composite regex from a mix
     of regex strings and verbatim strings.

13.6.2 Portable Scheme regular expressions
------------------------------------------

This provides the procedures ‘pregexp’, ‘pregexp‑match‑positions’,
‘pregexp‑match’, ‘pregexp‑split’, ‘pregexp‑replace’, ‘pregexp‑replace*’,
and ‘pregexp‑quote’.

   Before using them, you must require them:
     (require 'pregexp)

   These procedures have the same interface as the corresponding
‘regex-’ versions, but take slightly different pattern syntax.  The
replace commands use “‘\’” instead of “‘$’” to indicate substitutions.
Also, ‘pregexp‑split’ behaves differently from ‘regex‑split’ if the
pattern can match an empty string.

   See here for details
(http://www.ccs.neu.edu/home/dorai/pregexp/index.html).


File: kawa.info,  Node: Data structures,  Next: Eval and Environments,  Prev: Characters and text,  Up: Top

14 Data structures
******************

* Menu:

* Sequences::
* Lists::
* Vectors::
* Uniform vectors::
* Bytevectors::
* Ranges::
* Streams:: Lazy lists.
* Arrays::  Multi-dimensional Arrays
* Hash tables::


File: kawa.info,  Node: Sequences,  Next: Lists,  Up: Data structures

14.1 Sequences
==============

A “sequence” is a generalized list, consisting of zero or more values.
You can choose between a number of different kinds of sequence
implementations.  Scheme traditionally has *note lists: Lists. and *note
vectors: Vectors.  Any Java class that implements ‘java.util.List’ is a
sequence type.  Raw Java arrays can also be viewerd as a sequence, and
strings can be viewed a sequence (or vector) of characters.  Kawa also
provides *note uniform vectors: Uniform vectors.

   Sequence types differ in their API, but given a sequence type STYPE
you can construct instances of that type using the syntax:
     (STYPE V0 V1 .... VN)
   For example:
     (bytevector 9 8 7 6)  ⇒ #u8(9 8 7 6)

   For a raw Java class name JNAME you may need to use the empty keyword
‘||:’ to separate constructor parameters (if any) from sequence
elements, as in:
     (gnu.lists.U8Vector ||: 9 8 7 6)  ⇒ #u8(9 8 7 6)
   This syntax works with any type with a default constructor and a
1-argument ‘add’ method; see *note Allocating objects:: for details.
You can use the same syntax for allocating arrays, though array creation
supports *note more options: Creating-new-Java-arrays.

   To extract an element from Scheme sequence of type STYPE there is
usually a function ‘STYPE-ref’.  For example:
     (define vec1 (vector 5 6 7 8))
     (vector-ref vec1 2) ⇒ 7

   More concisely, you can use (Kawa-specific) function call syntax:
     (vec1 3) ⇒ 8

   The index can be another sequence, which creates a new sequence of
the selected indexes:
     (vec1 [3 0 2 1]) ⇒ #(8 5 7 6)
   It is convenient to use a *note “range”: Ranges. to select a
sub-sequence:
     (vec1 [1 <=: 3]) ⇒ #(6 7 8)
     (vec1 [2 <:]) ⇒ #(7 8)

   The same function call syntax also works for raw Java arrays (though
the index is restricted to an integer, not a sequence or array):
     (define arr1 (long[] 4 5 6 7))
     (arr1 3) ⇒ 7

   To assign to (replace) an element from a sequence of Scheme type
STYPE there is usually a function ‘STYPE-set!’:
     (vector-set! vec1 1 9)
     vec1 ⇒ #(5 9 7 8)

   Again, you can use the function call syntax:
     (set! (vec1 2) 'x)
     vec1 ⇒ #(5 9 x 8)

 -- Procedure: length seq
     Returns the number of elements of the SEQ.

          (length '(a b c))             ⇒  3
          (length '(a (b) (c d e)))     ⇒  3
          (length '())                  ⇒  0
          (length [3 4 [] 12])          ⇒  4
          (length (vector))             ⇒  0
          (length (int[] 7 6))          ⇒  2

     The length of a string is the number of characters (Unicode code
     points).  In contrast, the ‘length’ _method_ (of the ‘CharSequence’
     interface) returns the number of 16-bit code points:
          (length "Hello")              ⇒  5
          (define str1 "Hello \x1f603;!")
          (invoke str1 'length)         ⇒  9
          (length str1)                 ⇒  8 ; Used to return 9 in Kawa 2.x.
          (string-length str1)          ⇒  8


File: kawa.info,  Node: Lists,  Next: Vectors,  Prev: Sequences,  Up: Data structures

14.2 Lists
==========

A pair (sometimes called a “dotted pair”) is a record structure with two
fields called the car and cdr fields (for historical reasons).  Pairs
are created by the procedure ‘cons’.  The car and cdr fields are
accessed by the procedures ‘car’ and ‘cdr’.  The car and cdr fields are
assigned by the procedures ‘set-car!’ and ‘set-cdr!’.

   Pairs are used primarily to represent lists.  A “list” can be defined
recursively as either the empty list or a pair whose cdr is a list.
More precisely, the set of lists is defined as the smallest set X such
that:
   • The empty list is in X.
   • If LIST is in X, then any pair whose cdr field contains LIST is
     also in X.

   The objects in the car fields of successive pairs of a list are the
elements of the list.  For example, a two-element list is a pair whose
car is the first element and whose cdr is a pair whose car is the second
element and whose cdr is the empty list.  The length of a list is the
number of elements, which is the same as the number of pairs.

   The empty list is a special object of its own type.  It is not a
pair, it has no elements, and its length is zero.

   _Note:_ The above definitions imply that all lists have finite length
and are terminated by the empty list.

   The most general notation (external representation) for Scheme pairs
is the “dotted” notation ‘(C1 . C2 )’ where C1 is the value of the car
field and C2 is the value of the cdr field.  For example ‘(4 . 5)’ is a
pair whose car is 4 and whose cdr is 5.  Note that ‘(4 . 5)’ is the
external representation of a pair, not an expression that evaluates to a
pair.

   A more streamlined notation can be used for lists: the elements of
the list are simply enclosed in parentheses and separated by spaces.
The empty list is written ‘()’.  For example,
     (a b c d e)
   and
     (a . (b . (c . (d . (e . ())))))
   are equivalent notations for a list of symbols.

   A chain of pairs not ending in the empty list is called an “improper
list”.  Note that an improper list is not a list.  The list and dotted
notations can be combined to represent improper lists:
     (a b c . d)
   is equivalent to
     (a . (b . (c . d)))

   _Needs to finish merging from R7RS!_

 -- Procedure: make-list k [fill]
     Returns a newly allocated list of K elements.  If a second argument
     is given, the each element is initialized to FILL.  Otherwise the
     initial contents of each element is unspecified.
          (make-list 2 3)   ⇒ (3 3)

14.2.1 SRFI-1 list library
--------------------------

The SRFI-1 List Library (http://srfi.schemers.org/srfi-1/srfi-1.html) is
available, though not enabled by default.  To use its functions you must
‘(require 'list-lib)’ or ‘(require 'srfi-1)’.
     (require 'list-lib)
     (iota 5 0 -0.5) ⇒ (0.0 -0.5 -1.0 -1.5 -2.0)

 -- Procedure: reverse! list
     The result is a list consisting of the elements of LIST in reverse
     order.  No new pairs are allocated, instead the pairs of LIST are
     re-used, with ‘cdr’ cells of LIST reversed in place.  Note that if
     LIST was pair, it becomes the last pair of the reversed result.

14.2.2 SRFI-101 Purely Functional Random-Access Pairs and Lists
---------------------------------------------------------------

SRFI-101 (http://srfi.schemers.org/srfi-101/srfi-101.html) specifies
immutable (read-only) lists with fast (logarithmic) indexing and
functional update (i.e.  return a modified list).  These are implemented
by a ‘RAPair’ class which extends the generic ‘pair’ type, which means
that most code that expects a standard list will work on these lists as
well.


File: kawa.info,  Node: Vectors,  Next: Uniform vectors,  Prev: Lists,  Up: Data structures

14.3 Vectors
============

Vectors are heterogeneous structures whose elements are indexed by
integers.  A vector typically occupies less space than a list of the
same length, and the average time needed to access a randomly chosen
element is typically less for the vector than for the list.

   The _length_ of a vector is the number of elements that it contains.
This number is a non–negative integer that is fixed when the vector is
created.  The _valid indices_ of a vector are the exact non–negative
integer objects less than the length of the vector.  The first element
in a vector is indexed by zero, and the last element is indexed by one
less than the length of the vector.

   Vectors are written using the notation ‘#(OBJ ...)’.  For example, a
vector of length 3 3 containing the number zero in element 0, the list
‘(2 2 2 2)’ in element 1, and the string ‘"Anna"’ in element 2 can be
written as following:
     #(0 (2 2 2 2) "Anna")
   Note that this is the external representation of a vector.  In Kawa,
a vector datum is self-evaluating, but for style (and compatibility with
R7RS) is is suggested you quote a vector constant:
     ’#(0 (2 2 2 2) "Anna")  ⇒ #(0 (2 2 2 2) "Anna")

   Compare these different ways of creating a vector:
‘(vector a b c)’
     In this case ‘a’, ‘b’, and ‘c’ are expressions evaluated at
     run-time and the results used to initialize a newly-allocated
     3-element vector.
‘[a b c]’
     Same as using vector, but more concise, and results in an immutable
     (non-modifiable) vector.
‘#(a b c)’
     This is reader syntax and creates a vector literal, at read-time,
     early in compile-time.  The symbols ‘a’, ‘b’, and ‘c’ are not
     evaluated but instead used literally.
‘`#(,a ,b ,c)’
     This is reader-syntax, using quasi-quotation, so ‘a’, ‘b’, and ‘c’
     are expressions evaluated at run-time.  This is equivalent to ‘[a b
     c]’ in that it results in an immutable vector.

 -- Type: vector
     The type of vector objects.

 -- Constructor: vector OBJ ...
     Return a newly allocated vector whose elements contain the given
     arguments.  Analogous to ‘list’.

          (vector 'a 'b 'c)               ⇒  #(a b c)

     Alternatively, you can use square-bracket syntax, which results in
     an immutable vector:
          ['a 'b 'c]               ⇒  #(a b c)

 -- Procedure: make-vector K
 -- Procedure: make-vector K FILL
     Return a newly allocated vector of K elements.  If a second
     argument is given, then each element is initialized to FILL.
     Otherwise the initial contents of each element is ‘#!null’.

 -- Procedure: vector? OBJ
     Return ‘#t’ if OBJ is a vector, ‘#f’ otherwise.

 -- Procedure: vector-length VECTOR
     Return the number of elements in VECTOR as an exact integer.

 -- Procedure: vector-ref VECTOR K
     It is an error if K is not a valid index of VECTOR.  The
     ‘vector-ref’ procedure returns the contents of element K of VECTOR.

          (vector-ref '#(1 1 2 3 5 8 13 21) 5)     ⇒  8
          (vector-ref '#(1 1 2 3 5 8 13 21)
            (inexact->exact (round (* 2 (acos -1)))))
          ⇒ 13

 -- Procedure: vector-set! VECTOR K OBJ
     It is an error if K is not a valid index of VECTOR.  The
     ‘vector-set!’ procedure stores OBJ in element K of VECTOR, and
     returns no values.

          (let ((vec (vector 0 '(2 2 2 2) "Anna")))
            (vector-set! vec 1 '("Sue" "Sue"))
            vec)
            ⇒  #(0 ("Sue" "Sue") "Anna")

          (vector-set! '#(0 1 2) 1 "doe")
            ⇒  error    ;; constant vector

   A concise alternative to ‘vector-ref’ and ‘vector-set!’ is to use
function call syntax.  For example:
     (let ((vec (vector 0 '(2 2 2 2) "Anna")))
       (set! (vec 1) '("Sue" "Sue"))
       (list (vec 2) (vec 1)))
       ⇒  ("Anna" ("Sue" "Sue"))

 -- Procedure: vector->list VECTOR [START [END]]
     The ‘vector->list’ procedure returns a newly allocated list of the
     objects contained in the elements of VECTOR between START and END.

          (vector->list '#(dah dah didah))        ⇒  (dah dah didah)
          (vector->list '#(dah dah didah) 1 2)    ⇒  (dah)

 -- Procedure: list->vector LIST
     The ‘list->vector’ procedure returns a newly created vector
     initialized to the elements of the list LIST, in order.
          (list->vector '(dididit dah))           ⇒  #(dididit dah)

 -- Procedure: vector-copy vector [start [end]]
     Returns a newly allocated copy of the elements of the given VECTOR
     between START and END .  The elements of the new vector are the
     same (in the sense of ‘eqv?’) as the elements of the old.

          (define a #(1 8 2 8)) ; a may be immutable
          (define b (vector-copy a))
          (vector-set! b 0 3)   ; b is mutable
          b                     ⇒      #(3 8 2 8)
          (define c (vector-copy b 1 3))
          c                     ⇒ #(8 2)

 -- Procedure: vector-copy! to at from [start [end]]
     Copies the elements of vector from between start and end to vector
     to, starting at at.  The order in which elements are copied is
     unspecified, except that if the source and destination overlap,
     copying takes place as if the source is first copied into a
     temporary vector and then into the destination.  This can be
     achieved without allocating storage by making sure to copy in the
     correct direction in such circumstances.

     It is an error if AT is less than zero or greater than the length
     of TO.  It is also an error if ‘(- (vector-length TO) AT)’ is less
     than ‘(- END START)’.

          (define a (vector 1 2 3 4 5))
          (define b (vector 10 20 30 40 50))
          (vector-copy! b 1 a 0 2)
          b    ⇒ #(10 1 2 40 50)

 -- Procedure: vector-append ARG...
     Creates a newly allocated vector whose elements are the
     concatenation of the elements of the given arguments.  Each ARG may
     be a vector or a list.
          (vector-append #(a b c) #(d e f))
              ⇒ #(a b c d e f)

 -- Procedure: vector-fill! VECTOR FILL [START [END]]
     Stores FILL in in the elements of VECTOR between START and END.
          (define a (vector 1 2 3 4 5))
          (vector-fill! a 'smash 2 4)
          a  ⇒ #(1 2 smash smash 5)

   The procedures ‘vector-map’ and ‘vector-for-each’ are documented in
*note Mapping functions::.


File: kawa.info,  Node: Uniform vectors,  Next: Bytevectors,  Prev: Vectors,  Up: Data structures

14.4 Uniform vectors
====================

Uniform vectors are vectors whose elements are of the same numeric type.
The are defined by SRFI-4 (http://srfi.schemers.org/srfi-4/srfi-4.html).
The type names (such as ‘s8vector’) are a Kawa extension.

     UNIFORM-VECTOR ::= ‘#’ UNIFORM-TAG LIST
     UNIFORM-TAG ::= ‘f32’ | ‘f64’
         | ‘s8’ | ‘s16’ | ‘s32’ | ‘s64’
         | ‘u8’ | ‘u16’ | ‘u32’ | ‘u64’

   This example is a literal for a 5-element vector of unsigned short
(‘ushort’) values:
     (define uvec1 #u16(64000 3200 160 8 0))

   Since a uniform vector is a sequence, you can use function-call
notation to index one.  For example:
     (uvec1 1) ⇒ 3200
   In this case the result is a primitive unsigned short (‘ushort’),
which is converted to a ‘gnu.math.UShort’ if an object is needed.

 -- Type: s8vector
     The type of uniform vectors where each element can contain a signed
     8-bit integer.  Represented using an array of ‘byte’.

 -- Type: u8vector
     The type of uniform vectors where each element can contain an
     unsigned 8-bit integer.  Represented using an array of ‘<byte>’,
     but each element is treated as if unsigned.

     This type is a synonym for ‘bytevector’, which has *note extra
     functions: Bytevectors.

 -- Type: s16vector
     The type of uniform vectors where each element can contain a signed
     16-bit integer.  Represented using an array of ‘short’.

 -- Type: u16vector
     The type of uniform vectors where each element can contain an
     unsigned 16-bit integer.  Represented using an array of ‘short’,
     but each element is treated as if unsigned.

 -- Type: s32vector
     The type of uniform vectors where each element can contain a signed
     32-bit integer.  Represented using an array of ‘int’.

 -- Type: u32vector
     The type of uniform vectors where each element can contain an
     unsigned 32-bit integer.  Represented using an array of ‘int’, but
     each element is treated as if unsigned.

 -- Type: s64vector
     The type of uniform vectors where each element can contain a signed
     64-bit integer.  Represented using an array of ‘long’.

 -- Type: u64vector
     The type of uniform vectors where each element can contain an
     unsigned 64-bit integer.  Represented using an array of ‘long’, but
     each element is treated as if unsigned.

 -- Type: f32vector
     The type of uniform vectors where each element can contain a 32-bit
     floating-point real.  Represented using an array of ‘float’.

 -- Type: f64vector
     The type of uniform vectors where each element can contain a 64-bit
     floating-point real.  Represented using an array of ‘double’.

 -- Procedure: s8vector? value
 -- Procedure: u8vector? value
 -- Procedure: s16vector? value
 -- Procedure: u16vector? value
 -- Procedure: s32vector? value
 -- Procedure: u32vector? value
 -- Procedure: s64vector? value
 -- Procedure: u64vector? value
 -- Procedure: f32vector? value
 -- Procedure: f64vector? value
     Return true iff VALUE is a uniform vector of the specified type.

 -- Procedure: make-s8vector n [value]
 -- Procedure: make-u8vector n [value]
 -- Procedure: make-s16vector n [value]
 -- Procedure: make-u16vector n [value]
 -- Procedure: make-s32vector n [value]
 -- Procedure: make-u32vector n [value]
 -- Procedure: make-s64vector n [value]
 -- Procedure: make-u64vector n [value]
 -- Procedure: make-f32vector n [value]
 -- Procedure: make-f64vector n [value]
     Create a new uniform vector of the specified type, having room for
     N elements.  Initialize each element to VALUE if it is specified;
     zero otherwise.

 -- Constructor: s8vector value ...
 -- Constructor: u8vector value ...
 -- Constructor: s16vector value ..
 -- Constructor: u16vector value ...
 -- Constructor: s32vector value ...
 -- Constructor: u32vector value ...
 -- Constructor: s64vector value ...
 -- Constructor: u64vector value ...
 -- Constructor: f32vector value ...
 -- Constructor: f64vector value ...
     Create a new uniform vector of the specified type, whose length is
     the number of VALUEs specified, and initialize it using those
     VALUEs.

 -- Procedure: s8vector-length v
 -- Procedure: u8vector-length v
 -- Procedure: s16vector-length v
 -- Procedure: u16vector-length v
 -- Procedure: s32vector-length v
 -- Procedure: u32vector-length v
 -- Procedure: s64vector-length v
 -- Procedure: u64vector-length v
 -- Procedure: f32vector-length v
 -- Procedure: f64vector-length v
     Return the length (in number of elements) of the uniform vector V.

 -- Procedure: s8vector-ref v i
 -- Procedure: u8vector-ref v i
 -- Procedure: s16vector-ref v i
 -- Procedure: u16vector-ref v i
 -- Procedure: s32vector-ref v i
 -- Procedure: u32vector-ref v i
 -- Procedure: s64vector-ref v i
 -- Procedure: u64vector-ref v i
 -- Procedure: f32vector-ref v i
 -- Procedure: f64vector-ref v i
     Return the element at index I of the uniform vector V.

 -- Procedure: s8vector-set! v i x
 -- Procedure: u8vector-set! v i x
 -- Procedure: s16vector-set! v i x
 -- Procedure: u16vector-set! v i x
 -- Procedure: s32vector-set! v i x
 -- Procedure: u32vector-set! v i x
 -- Procedure: s64vector-set! v i x
 -- Procedure: u64vector-set! v i x
 -- Procedure: f32vector-set! v i x
 -- Procedure: f64vector-set! v i x
     Set the element at index I of uniform vector V to the value X,
     which must be a number coercible to the appropriate type.

 -- Procedure: s8vector->list v
 -- Procedure: u8vector->list v
 -- Procedure: s16vector->list v
 -- Procedure: u16vector->list v
 -- Procedure: s32vector->list v
 -- Procedure: u32vector->list v
 -- Procedure: s64vector->list v
 -- Procedure: u64vector->list v
 -- Procedure: f32vector->list v
 -- Procedure: f64vector->list v
     Convert the uniform vetor V to a list containing the elments of V.

 -- Procedure: list->s8vector l
 -- Procedure: list->u8vector l
 -- Procedure: list->s16vector l
 -- Procedure: list->u16vector l
 -- Procedure: list->s32vector l
 -- Procedure: list->u32vector l
 -- Procedure: list->s64vector l
 -- Procedure: list->u64vector l
 -- Procedure: list->f32vector l
 -- Procedure: list->f64vector l
     Create a uniform vector of the appropriate type, initializing it
     with the elements of the list L.  The elements of L must be numbers
     coercible the new vector’s element type.

14.4.1 Relationship with Java arrays
------------------------------------

Each uniform array type is implemented as an “underlying Java array”,
and a length field.  The underlying type is ‘byte[]’ for ‘u8vector’ or
‘s8vector’; ‘short[]’ for ‘u16vector’ or ‘u16vector’; ‘int[]’ for
‘u32vector’ or ‘s32vector’; ‘long[]’ for ‘u64vector’ or ‘s64vector’;
‘float[]’ for ‘f32vector’; and ‘double[]’ for ‘f32vector’.  The length
field allows a uniform array to only use the initial part of the
underlying array.  (This can be used to support Common Lisp’s fill
pointer feature.)  This also allows resizing a uniform vector.  There is
no Scheme function for this, but you can use the ‘setSize’ method:
     (invoke some-vector 'setSize 200)

   If you have a Java array, you can create a uniform vector sharing
with the Java array:
     (define arr :: byte[] ((primitive-array-new byte) 10))
     (define vec :: u8vector (make u8vector arr))
   At this point ‘vec’ uses ‘arr’ for its underlying storage, so changes
to one affect the other.  It ‘vec’ is re-sized so it needs a larger
underlying array, then it will no longer use ‘arr’.


File: kawa.info,  Node: Bytevectors,  Next: Ranges,  Prev: Uniform vectors,  Up: Data structures

14.5 Bytevectors
================

“Bytevectors” represent blocks of binary data.  They are fixed-length
sequences of bytes, where a BYTE is an exact integer in the range [0,
255].  A bytevector is typically more space-efficient than a vector
containing the same values.

   The length of a bytevector is the number of elements that it
contains.  This number is a non-negative integer that is fixed when the
bytevector is created.  The valid indexes of a bytevector are the exact
non-negative integers less than the length of the bytevector, starting
at index zero as with vectors.

   The ‘bytevector’ type is equivalent to the ‘u8vector’ *note uniform
vector: Uniform vectors. type, but is specified by the R7RS standard.

   Bytevectors are written using the notation ‘#u8(byte . . . )’.  For
example, a bytevector of length 3 containing the byte 0 in element 0,
the byte 10 in element 1, and the byte 5 in element 2 can be written as
following:
     #u8(0 10 5)
   Bytevector constants are self-evaluating, so they do not need to be
quoted in programs.

 -- Type: bytevector
     The type of bytevector objects.

 -- Constructor: bytevector BYTE ...
     Return a newly allocated bytevector whose elements contain the
     given arguments.  Analogous to ‘vector’.
          (bytevector 1 3 5 1 3 5)  ⇒  #u8(1 3 5 1 3 5)
          (bytevector)  ⇒  #u8()

 -- Procedure: bytevector? OBJ
     Return ‘#t’ if OBJ is a bytevector, ‘#f’ otherwise.

 -- Procedure: make-bytevector k
 -- Procedure: make-bytevector k byte
     The ‘make-bytevector’ procedure returns a newly allocated
     bytevector of length K.  If BYTE is given, then all elements of the
     bytevector are initialized to BYTE, otherwise the contents of each
     element are unspecified.
          (make-bytevector 2 12) ⇒ #u8(12 12)

 -- Procedure: bytevector-length bytevector
     Returns the length of BYTEVECTOR in bytes as an exact integer.

 -- Procedure: bytevector-u8-ref bytevector k
     It is an error if K is not a valid index of BYTEVECTOR.  Returns
     the Kth byte of BYTEVECTOR.
          (bytevector-u8-ref ’#u8(1 1 2 3 5 8 13 21) 5)
            ⇒ 8

 -- Procedure: bytevector-u8-set! bytevector k byte
     It is an error if K is not a valid index of BYTEVECTOR.  Stores
     BYTE as the Kth byte of BYTEVECTOR.
          (let ((bv (bytevector 1 2 3 4)
            (bytevector-u8-set! bv 1 3)
            bv)
            ⇒ #u8(1 3 3 4)

 -- Procedure: bytevector-copy bytevector [start [end]]
     Returns a newly allocated bytevector containing the bytes in
     BYTEVECTOR between START and END.

          (define a #u8(1 2 3 4 5))
          (bytevector-copy a 2 4))
              ⇒ #u8(3 4)

 -- Procedure: bytevector-copy! to at from [start [end]]
     Copies the bytes of bytevectorFROM between START and END to
     bytevector TO, starting at AT.  The order in which bytes are copied
     is unspecified, except that if the source and destination overlap,
     copying takes place as if the source is first copied into a
     temporary bytevector and then into the destination.  This is
     achieved without allocating storage by making sure to copy in the
     correct direction in such circumstances.

     It is an error if AT is less than zero or greater than the length
     of TO.  It is also an error if ‘(- (bytevector-length TO) AT)’ is
     less than ‘(- END START)’.

          (define a (bytevector 1 2 3 4 5))
          (define b (bytevector 10 20 30 40 50))
          (bytevector-copy! b 1 a 0 2)
          b        ⇒ #u8(10 1 2 40 50)

 -- Procedure: bytevector-append bytevector...
     Returns a newly allocated bytevector whose elements are the
     concatenation of the elements in the given bytevectors.

          (bytevector-append #u8(0 1 2) #u8(3 4 5))
                  ⇒  #u8(0 1 2 3 4 5)

14.5.1 Converting to or from strings
------------------------------------

 -- Procedure: utf8->string bytevector [start [end]]
     This procedure decodes the bytes of a bytevector between START and
     END, interpreting as a UTF-8-encoded string, and returns the
     corresponding string.  It is an error for BYTEVECTOR to contain
     invalid UTF-8 byte sequences.
          (utf8->string #u8(#x41))  ⇒ "A"

 -- Procedure: utf16->string bytevector [start [end]]
 -- Procedure: utf16be->string bytevector [start [end]]
 -- Procedure: utf16le->string bytevector [start [end]]
     These procedures interpret their <var>bytevector</var> argument as
     a UTF-16 encoding of a sequence of characters, and return an
     istring containing that sequence.

     The bytevector subrange given to ‘utf16->string’ may begin with a
     byte order mark (BOM); if so, that BOM determines whether the rest
     of the subrange is to be interpreted as big-endian or
     little-endian; in either case, the BOM will not become a character
     in the returned string.  If the subrange does not begin with a BOM,
     it is decoded using the same implementation-dependent endianness
     used by ‘string->utf16’.

     The ‘utf16be->string’ and ‘utf16le->string’ procedures interpret
     their inputs as big-endian or little-endian, respectively.  If a
     BOM is present, it is treated as a normal character and will become
     part of the result.

     It is an error if ‘(- END START)’ is odd, or if the bytevector
     subrange contains invalid UTF-16 byte sequences.

 -- Procedure: string->utf8 string [start [end]]
     This procedure encodes the characters of a string between START and
     END and returns the corresponding bytevector, in UTF-8 encoding.
          (string->utf8 "λ")     ⇒ " #u8(#xCE #xBB)

 -- Procedure: string->utf16 string [start [end]]
 -- Procedure: string->utf16be string [start [end]]
 -- Procedure: string->utf16le string [start [end]]
     These procedures return a newly allocated (unless empty) bytevector
     containing a UTF-16 encoding of the given substring.

     The bytevectors returned by ‘string->utf16be’ and ‘string->utf16le’
     do not contain a byte-order mark (BOM); ‘string->utf16be’> returns
     a big-endian encoding, while ‘string->utf16le’ returns a
     little-endian encoding.

     The bytevectors returned by ‘string->utf16’ begin with a BOM that
     declares an implementation-dependent endianness, and the bytevector
     elements following that BOM encode the given substring using that
     endianness.

     _Rationale:_ These procedures are consistent with the Unicode
     standard.  Unicode suggests UTF-16 should default to big-endian,
     but Microsoft prefers little-endian.


File: kawa.info,  Node: Ranges,  Next: Streams,  Prev: Bytevectors,  Up: Data structures

14.6 Ranges
===========

A “range” is an immutable sequence of values that increase “linearly” -
i.e.  by a fixed amount.  Most commonly it’s a sequence of consequtive
integers.  An example of the syntax is ‘[3 <: 7]’ which evaluates to the
sequence ‘[3 4 5 6]’.  You can specify an explicit increment with a
‘by:’ option.  There are multiple ways to specify when the sequence
stops.  For example ‘[3 by 2 <=: 7]’ is the even numbers from 3 up to 7
(inclusive, because of the ‘<=’).

   Ranges are very useful for loop indexes, or selecting a sub-sequence.
If you have a sequence Q and a range R, and you use the syntax ‘(Q R)’
to “apply”Q with the argument R, is result is to select elements of Q
with indexes in R.
     ("ABCDEFG" [1 by: 2 <: 7])  ⇒ "BDF"

   A range can be “unbounded”, or non-finite, if you leave off the end
value.  For example ‘[3 by: 2]’ is the odd integers starting at 3.

     UNBOUNDED-RANGE ::=
       ‘[’ START-EXPRESSION ‘by:’ STEP-EXPRESSION ‘]’
       | ‘[’ START-EXPRESSION ‘<:’ ‘]’

   The expression ‘[START by: STEP]’ evaluates to an infinite sequence
of values, starting with START, and followed by ‘(+ START STEP)’, ‘(+
START (* 2 STEP))’, and so on.

   The syntax ‘[START-EXPRESSION <:]’ is shorthand for
‘[START-EXPRESSION by: 1]’.

     BOUNDED-RANGE ::= ‘[’ START-EXPRESSION [‘by:’ STEP-EXPRESSION] RANGE-END ‘]’
     RANGE-END ::= ‘<:’ END-EXPRESSION
       | ‘<=:’ END-EXPRESSION
       | ‘>:’ END-EXPRESSION
       | ‘>=:’ END-EXPRESSION
       | ‘size:’ SIZE-EXPRESSION

   A bounded range takes an initial subsequence of the unbounded range
specified by the START-EXPRESSION and optional STEP-EXPRESSION.  The
different END-EXPRESSION variants provide different ways to specify the
initial subsequence.

   If ‘size: SIZE’ is specified, then the resulting range is the first
SIZE elements of unbounded sequence.

   In the ‘<: END’ or ‘<=: END’ cases then the sequence counts up: The
STEP must be positive, and defaults to 1.  The resulting values are
those X such that ‘(< X END)’, or ‘(<= X END)’, respectively.

   In the ‘>: END’ or ‘>=: END’ cases then the sequence counts down: The
STEP must be negative, and defaults to -1.  The resulting values are
those X such that ‘(> X END)’, or ‘(>= X END)’, respectively.

   The START-EXPRESSION, STEP-EXPRESSION, and SIZE-EXPRESSION must
evaluate to real numbers, not necessarily integers.  For example: ‘[1
by: 0.5 <=: 3.0]’ is ‘[1.0 1.5 2.0 2.5 3.0]’.

   The two pseudo-ranges ‘[<:]’ and ‘[>:]’ are useful as array indexes.
They mean “all of the valid indexes” of the array being indexed.  For
increasing index values use ‘[<:]’; for decreasing index values (i.e.
reversing) use ‘[>:]’.


File: kawa.info,  Node: Streams,  Next: Arrays,  Prev: Ranges,  Up: Data structures

14.7 Streams - lazy lists
=========================

Streams, sometimes called lazy lists, are a sequential data structure
containing elements computed only on demand.  A stream is either null or
is a pair with a stream in its cdr.  Since elements of a stream are
computed only when accessed, streams can be infinite.  Once computed,
the value of a stream element is cached in case it is needed again.

   _Note:_ These are not the same as Java 8 streams.

     (require 'srfi-41)
     (define fibs
       (stream-cons 1
         (stream-cons 1
           (stream-map +
             fibs
             (stream-cdr fibs)))))
     (stream->list 8 fibs) ⇒ (1 1 2 3 5 8 13 21)

   See the SRFI 41 specification
(http://srfi.schemers.org/srfi-41/srfi-41.html) for details.

   The Kawa implementations builds on *note promises: Lazy evaluation.
The ‘stream-null’ value is a promise that evaluates to the empty list.
The result of ‘stream-cons’ is an eager immutable pair whose ‘car’ and
‘cdr’ properties return promises.


File: kawa.info,  Node: Arrays,  Next: Hash tables,  Prev: Streams,  Up: Data structures

14.8 Multi-dimensional Arrays
=============================

Arrays are heterogeneous data structures that generaize vectors to
multiple indexes or dimensions.  Instead of a single integer index,
there are multiple indexes: An index is a vector of integers; the length
of a valid index sequence is the rank or the number of dimensions of an
array.

   Kawa multi-dimensional arrays follows the by SRFI-25 specification
(http://srfi.schemers.org/srfi-25/srfi-25.html), with additions from
Racket’s math.array (https://docs.racket-lang.org/math/array.html)
package and other sources.

   An array whose rank is 1, and where the (single) lower bound is 0 is
a sequence.  Furthermore, if such an array is simple (not created by
‘share-array’) it will be implemented using a ‘<vector>’.  Uniform
vectors and strings are also arrays in Kawa.

   A rank-0 array has a single value.  It is essentially a box for that
value.  Functions that require arrays may treat non-arrays as a rank-0
array containing that value.

   An array of rank 2 is frequently called a “matrix”.

   Note that Kawa arrays are distinct from Java (native) arrays.  The
latter is a simpler one-dimensional vector-like data structure, which is
used to implement Kawa arrays and vectors.

 -- Procedure: array? obj
     Returns ‘#t’ if OBJ is an array, otherwise returns ‘#f’.

14.8.1 Array shape
------------------

The “shape” of an array consists of bounds for each index.

   The lower bound B and the upper bound E of a dimension are exact
integers with ‘(<= B E)’.  A valid index along the dimension is an exact
integer I that satisfies both ‘(<= B I)’ and ‘(< I E)’.  The length of
the array along the dimension is the difference ‘(- E B)’.  The size of
an array is the product of the lengths of its dimensions.

   There is no separate data type for a shape.  The canonical
representation for a shape (a “canonical shape”) is a rank-2 array where
the first index is the dimension (zero-based), and the second index is 0
or 1: Elements (I 0) and (I 1) are respectively the lower bound and
upper bound of dimension I.

   For convenience, the procedures that require a shape can accept a
SHAPE-SPECIFIER, as if converted by the procedure ‘->shape’.  For
example ‘(array-reshape ARRAY SHAPE)’ is equivalent to ‘(array-reshape
ARRAY (->shape SHAPE))’.

 -- Procedure: ->shape specifier
     Convert the shape specifier SPECIFIER to a canonical shape.  The
     SPECIFIER must be either a canonical shape, or vector with one
     element for each dimension, as described below.  We use as examples
     a 2*3 array with lower bounds 0 and a 3*4 array with lower bounds
     1.
        • A vector of simple integers.  Each integer E is an upper
          bound, with a zero lower bound.  Equivalent to the range ‘[0
          <: E]’.

          A specifier for the first examples is ‘#(2 3)’, and the second
          is not expressible.
        • A vector of lists of length 2.  The first element of each list
          is the lower bound, and the second is the upper bound.

          Examples: ‘#((0 2) (0 3))’ and ‘#((1 3) (1 4))’.
        • A vector of simple *note ranges: Ranges, one for each
          dimension, all of who are bounded (finite), consist of integer
          values, and have a STEP of 1.  Each range, which is usually
          written as ‘[B <: E]’, expresses the bounds of the
          corresponding dimension For the first example you can use ‘[[0
          <: 2] [0 <=: 2]]’; for the second you can use ‘[[1 <: 3] [1
          size: 4]]’.
        • A vector consisting of a mix of integers, length-2 lists, and
          ranges.

          Examples: ‘#(2 (0 3))’ and ‘['(1 3) [1 size: 4]]’.
        • A canonical shape: A rank-2 array S whose own shape is ‘[R
          2]’.  For each dimension K (where ‘(<= K 0)’ and ‘(< K R)’),
          the lower bound B_{K} is ‘(S K 0)’, and the upper bound E_{K}
          is ‘(S K 1)’.

          Examples: ‘#2a((0 2) (0 3))’ and ‘#2a((1 3) (1 4))’.

 -- Procedure: shape bound ...
     Returns a shape.  The sequence BOUND ...  must consist of an even
     number of exact integers that are pairwise not decreasing.  Each
     pair gives the lower and upper bound of a dimension.  If the shape
     is used to specify the dimensions of an array and BOUND ...  is the
     sequence B0 E0 ...  BK EK ...  of N pairs of bounds, then a valid
     index to the array is any sequence J0 ...  JK ...  of N exact
     integers where each JK satisfies ‘(<= BK JK)’ and ‘(< JK EK)’.

     The shape of a D-dimensional array is a D * 2 array where the
     element at K 0 contains the lower bound for an index along
     dimension K and the element at K 1 contains the corresponding upper
     bound, where K satisfies ‘(<= 0 K)’ and ‘(< K D)’.

     ‘(shape @BOUNDS)’ is equivalent to: ‘(array [2 (/ (length BOUNDS)
     2)] @BOUNDS)’

 -- Procedure: array-shape array
     Return the shape of ARRAY in the canonical (r 2) form.  It is an
     error to attempt to modify the shape array.

 -- Procedure: array-rank array
     Returns the number of dimensions of ARRAY.
          (array-rank
            (make-array (shape 1 2 3 4)))
     Returns 2.

 -- Procedure: array-start array k
     Returns the lower bound (inclusive) for the index along dimension
     K.  This is most commonly 0.

 -- Procedure: array-end array k
     Returns the upper bound for the index along dimension K.  The bound
     is exclusive - i.e.  the first integer higher than the last legal
     index.

 -- Procedure: array-size array
     Return the total number of elements of ARRAY.  This is the product
     of ‘(- (array-end ARRAY K) (array-start ARRAY K))’ for every valid
     K.

14.8.2 Array types
------------------

 -- Type: array
 -- Type: arrayN
 -- Type: array[ETYPE]
 -- Type: arrayN[ETYPE]

     The type ‘array’ matches all array values.  The type ‘arrayN’,
     where N is an integer matches array of rank N.  For example
     ‘array2’ matches rank-2 array - i.e.  matrixes.

     You can optionally specify the element type ETYPE.  This can be a
     primitive type.  For example a ‘array2[double]’ is a rank-2 array
     whose elements are ‘double’ values.

14.8.3 Array literals and printing
----------------------------------

An array literal starts with ‘#’ followed by its rank, followed by a tag
that describes the underlying vector (by default ‘a’), optionally
followed by information about its shape, and finally followed by the
cells, organized into dimensions using parentheses.

   For example, ‘#2a((11 12 13) (21 22 23))’ is a rank-2 array (a
matrix) whose shape is ‘[2 3]’ or equivalently ‘[[0 <: 2] [0 <: 3]]’.
It is pretty-printed as:
     ╔#2a:2:3═╗
     ║11│12│13║
     ╟──┼──┼──╢
     ║21│22│23║
     ╚══╧══╧══╝

     ARRAY-LITERAL ::= ARRAY-LITERAL-HEADER DATUM
     ARRAY-LITERAL-HEADER ::= ‘#’ RANK VECTAG ARRAY-BOUND^{*}
     ARRAY-BOUND ::= [‘@’LOWER]‘:’LENGTH | ‘@’LOWER
     VECTAG ::= ‘a’ | UNIFORM-TAG

   The VECTAG specifies the type of the elements of the array.

   Following the VECTAG you can optionally include information about the
shape: For each dimension you can optionally specify the lower bounds
(after the character ‘"@"’), followed by the length of the dimension
(after the character ‘":"’).  The shape information is required if a
lower bound is non-zero, or any length is zero.

   The DATUM contains the elements in a nested-list format: a rank-1
array (i.e.  vector) uses a single list, a rank-2 array uses a
list-of-lists, and so on.  The elements are in lexicographic order.

   A uniform u32 array of rank 2 with index ranges 2..3 and 3..4:
     #2u32@2@3((1 2) (2 3))

   This syntax follows Common Lisp with Guile extensions
(https://www.gnu.org/software/guile/manual/html_node/Array-Syntax.html).
(Note that Guile prints rank-0 arrays with an extra set of parentheses.
Kawa follows Common Lisp in not doing so.)

   When an array is printed with the ‘write’ function, the result is an
‘array-literal’.  Printing with ‘display’ formats the array in a
rectangular grid using the ‘format-array’ procedure.  (Note that
‘format-array’ is only used when the output is in column 0, because Kawa
has very limited support for printing rectangles.)

 -- Procedure: format-array value [port] [element-format]
     Produce a nice “pretty” display for VALUE, which is usually an
     array.

     If PORT is an output port, the formatted output is written into
     that port.  Otherwise, PORT must be a boolean (one of ‘#t’ or
     ‘#f’).  If the port is ‘#t’, output is to the
     ‘(current-output-port)’.  If the port is ‘#f’ or no port is
     specified, the output is returned as a string.  If the port is
     specified and is ‘#t’ or an output-port, the result of the
     ‘format-array’ procedure is unspecified.  (This convention matches
     that of the ‘format’ procedure.)

     The top line includes an ‘array-literal-header’.  The lower bound
     are only printed if non-zero.  The dimension lengths are printed if
     there is room, or if one of them is zero.
          #|kawa:34|# (! arr (array [[1 <=: 2] [1 <=: 3]]
          #|.....35|#   #2a((1 2) (3 4)) 9 #2a((3 4) (5 6))
          #|.....36|#   [42 43] #2a:1:3((8 7 6)) #2a((90 91) (100 101))))
          #|kawa:37|# arr
          ╔#2a@1:2@1:3════╤═════════╗
          ║#2a═╗  │      9│#2a═╗    ║
          ║║1│2║  │       │║3│4║    ║
          ║╟─┼─╢  │       │╟─┼─╢    ║
          ║║3│4║  │       │║5│6║    ║
          ║╚═╧═╝  │       │╚═╧═╝    ║
          ╟───────┼───────┼─────────╢
          ║╔#1a:2╗│#2a:1:3│╔#2a:2:2╗║
          ║║42│43║│║8│7│6║│║ 90│ 91║║
          ║╚══╧══╝│╚═╧═╧═╝│╟───┼───╢║
          ║       │       │║100│101║║
          ║       │       │╚═══╧═══╝║
          ╚═══════╧═══════╧═════════╝
     If ELEMENT-FORMAT is specified, it is a format string used for
     format each non-array:
          #|kawa:38|# (format-array arr "~4,2f")
          ╔#2a@1:2@1:3══╤════════════════╤═══════════════╗
          ║╔#2a:2:2══╗  │            9.00│╔#2a:2:2══╗    ║
          ║║1.00│2.00║  │                │║3.00│4.00║    ║
          ║╟────┼────╢  │                │╟────┼────╢    ║
          ║║3.00│4.00║  │                │║5.00│6.00║    ║
          ║╚════╧════╝  │                │╚════╧════╝    ║
          ╟─────────────┼────────────────┼───────────────╢
          ║╔#1a:2╤═════╗│╔#2a:1:3══╤════╗│╔#2a:2:2══════╗║
          ║║42.00│43.00║│║8.00│7.00│6.00║│║ 90.00│ 91.00║║
          ║╚═════╧═════╝│╚════╧════╧════╝│╟──────┼──────╢║
          ║             │                │║100.00│101.00║║
          ║             │                │╚══════╧══════╝║
          ╚═════════════╧════════════════╧═══════════════╝
     If the rank is more than 2, then each “layer” is printed separated
     by double lines.
          #|kawa:42|# (array-reshape [1 <=: 24] [3 2 4])
          ╔#3a:3:2:4══╗
          ║ 1│ 2│ 3│ 4║
          ╟──┼──┼──┼──╢
          ║ 5│ 6│ 7│ 8║
          ╠══╪══╪══╪══╣
          ║ 9│10│11│12║
          ╟──┼──┼──┼──╢
          ║13│14│15│16║
          ╠══╪══╪══╪══╣
          ║17│18│19│20║
          ╟──┼──┼──┼──╢
          ║21│22│23│24║
          ╚══╧══╧══╧══╝

14.8.4 Array construction
-------------------------

See also ‘array-reshape’

 -- Procedure: array shape obj ...
     Returns a new array whose shape is given by SHAPE and the initial
     contents of the elements are OBJ ...  in row major order.  The
     array does not retain a reference to SHAPE.

 -- Procedure: make-array shape
 -- Procedure: make-array shape value...
     Returns a newly allocated array whose shape is given by SHAPE.  If
     VALUE is provided, then each element is initialized to it.  If
     there is more than one VALUE, they are used in order, starting over
     when the VALUEs are exhausted.  If there is no VALUE, the initial
     contents of each element is unspecified.  (Actually, it is the
     ‘#!null’.)  The array does not retain a reference to SHAPE.

          #|kawa:16|# (make-array [2 4] 1 2 3 4 5)
          ╔#2a:2:4╗
          ║1│2│3│4║
          ╟─┼─┼─┼─╢
          ║5│1│2│3║
          ╚═╧═╧═╧═╝

     _Compatibility:_ Guile has an incompatible ‘make-array’ procedure.

 -- Procedure: build-array shape getter [setter]
     Construct a “virtual array” of the given SHAPE, which uses no
     storage for the elements.  Instead, elements are calculated
     on-demand by calling GETTER, which takes a single argument, an
     index vector.

     There is no caching or memoization.

          #|kawa:1|# (build-array [[10 <: 12] 3]
          #|....:2|#   (lambda (ind)
          #|....:3|#     (let ((x (ind 0)) (y (ind 1)))
          #|....:4|#       (- x y))))
          #2a@10:2:3
          ║10│ 9│8║
          ╟──┼──┼─╢
          ║11│10│9║
          ╚══╧══╧═╝

     The resulting array is mutable if a SETTER is provided.  The SETTER
     takes two arguments: An index vector, and the new value for the
     specified element.  Below is a simple and space-efficient (but
     slow) implementation of sparse arrays: Most element have a default
     initial value, but you can override specific elements.
          (define (make-sparse-array shape default-value)
            (let ((vals '())) ;; association list of (INDEX-VECTOR . VALUE)
              (build-array shape
                           (lambda (I)
                             (let ((v (assoc I vals)))
                               (if v (cdr v)
                                   default-value)))
                           (lambda (I newval)
                             (let ((v (assoc I vals)))
                               (if v
                                   (set-cdr! v newval)
                                   (set! vals (cons (cons I newval) vals))))))))

 -- Procedure: index-array shape
     Return a new immutable array of the specified SHAPE where each
     element is the corresponding row-major index.  Same as
     ‘(array-reshape [0 <: SIZE] SHAPE)’ where SIZE is the ‘array-size’
     of the resulting array.

          #|kawa:1|# (index-array [[1 <: 3] [2 <: 6]])
          #2a@1:2@2:4
          ║0│1│2│3║
          ╟─┼─┼─┼─╢
          ║4│5│6│7║
          ╚═╧═╧═╧═╝

14.8.5 Array indexing
---------------------

If you “call” an array as it it were a function, it is equivalent to
using ‘array-index-ref’, which is generalization of ‘array-ref’.  For
example, given a rank-2 array ARR with integer indexes I and J, the
following all get the element of ARR at index ‘[I J]’.
     (ARR I J)
     (array-index-ref ARR I J)
     (array-ref ARR I J)
     (array-ref ARR [I J])

   Using function-call notation or ‘array-index-ref’ (but not plain
‘array-ref’) you can do generalized APL-style slicing and indirect
indexing.  See under ‘array-index-ref’ for examples.

 -- Procedure: array-ref array k ...
 -- Procedure: array-ref array index
     Returns the contents of the element of ARRAY at index K ....  The
     sequence K ...  must be a valid index to ARRAY.  In the second
     form, INDEX must be either a vector (a 0-based 1-dimensional array)
     containing K ....
          (array-ref (array [2 3]
                        'uno 'dos 'tres
                        'cuatro 'cinco 'seis)
             1 0)
     Returns ‘cuatro’.
          (let ((a (array (shape 4 7 1 2) 3 1 4)))
             (list (array-ref a 4 1)
                   (array-ref a (vector 5 1))
                   (array-ref a (array (shape 0 2)
                                   6 1))))
     Returns ‘(3 1 4)’.

 -- Procedure: array-index-ref array index ...
     Generalized APL-style array indexing, where each INDEX can be
     either an array or an integer.

     If each INDEX is an integer, then the result is the same as
     ‘array-ref’.

     Otherwise, the result is an immutable array whose rank is the sum
     of the ranks of each INDEX.  An integer is treated as rank-0 array.

     If MARR is the result of ‘(array-index-ref ARR M_{1} M_{2} ...)’
     then:
          (MARR I_{11} I_{12} ... I_{21} I_{22} ...)
     is defined as:
          (ARR (M_{1} I_{11} I_{12} ...) (M_{2} I_{21} I_{22} ...) ...)
     Each M_{K} gets as many indexes as its rank.  If M_{K} is an
     integer, then it we use it directly without any indexing.

     Here are some examples, starting with simple indexing.
          #|kawa:1|# (define arr (array #2a((1 4) (0 4))
          #|.....2|#                    10 11 12 13 20 21 22 23 30 31 32 33))
          #|kawa:3|# arr
          ╔#2a@1:3:4══╗
          ║10│11│12│13║
          ╟──┼──┼──┼──╢
          ║20│21│22│23║
          ╟──┼──┼──┼──╢
          ║30│31│32│33║
          ╚══╧══╧══╧══╝
          #|kawa:4|# (arr 2 3)
          23
     If one index is a vector and the rest are scalar integers, then the
     result is a vector:
          #|kawa:5|# (arr 2 [3 1])
          #(23 21)
     You can select a “sub-matrix” when all indexes are vectors:
          #|kawa:6|# (arr [2 1] [3 1 3])
          ╔#2a:2:3═╗
          ║23│21│23║
          ╟──┼──┼──╢
          ║13│11│13║
          ╚══╧══╧══╝
     Using ranges for index vectors selects a rectangular sub-matrix.
          #|kawa:7|# (arr [1 <: 3] [1 <: 4])
          ╔#2a:2:3═╗
          ║11│12│13║
          ╟──┼──┼──╢
          ║21│22│23║
          ╚══╧══╧══╝
     You can add new dimensions:
          #|kawa:8|# (arr [2 1] #2a((3 1) (3 2)))
          #3a╤══╗
          ║23│21║
          ╟──┼──╢
          ║23│22║
          ╠══╪══╣
          ║13│11║
          ╟──┼──╢
          ║13│12║
          ╚══╧══╝
     The pseudo-range ‘[<:]’ can be used to select all the indexes along
     a dimension.  To select row 2 (1-origin):
          #|kawa:9|# (arr 2 [<:])
          #(20 21 22 23)
     To reverse the order use ‘[>:]’:
          #|kawa:10|# (arr 2 [>:])
          #(23 22 21 20)
     To select column 3:
          #|kawa:11|# (arr [<:] 3)
          #(13 23 33)
     If you actually want a column matrix (i.e.  with shape ‘[3 1]’ you
     can place the index in a single-element vector:
          #|kawa:12|# (arr [<:] [3])
          #2a╗
          ║13║
          ╟──╢
          ║23║
          ╟──╢
          ║33║
          ╚══╝
     To expand that column to 5 colums you can repeat the column index:
          #|kawa:13|# [3 by: 0 size: 5]
          #(3 3 3 3 3)
          #|kawa:14|# (arr [<:] [3 by: 0 size: 5])
          ╔#2a:3:5═╤══╤══╗
          ║13│13│13│13│13║
          ╟──┼──┼──┼──┼──╢
          ║23│23│23│23│23║
          ╟──┼──┼──┼──┼──╢
          ║33│33│33│33│33║
          ╚══╧══╧══╧══╧══╝

14.8.6 Modifying arrays
-----------------------

You can use ‘set!’ to modify one or multiple elements.  To modify a
single element:
     (set! (ARR INDEX ...) NEW-VALUE)
   is equivalent to
     (array-set! ARR INDEX ... NEW-VALUE)
   You can set a slice (or all of the elements).  In that case:
     (set! (ARR INDEX ...) NEW-ARRAY)
   is equivalent to:
     (array-copy! (array-index-share ARR INDEX ...) NEW-ARRAY)

 -- Procedure: array-set! array k ... obj
 -- Procedure: array-set! array index obj
     Stores OBJ in the element of ARRAY at index K ....  Returns the
     void value.  The sequence K ...  must be a valid index to ARRAY.
     In the second form, INDEX must be either a vector or a 0-based
     1-dimensional array containing K ....

          (let ((a (make-array
                      (shape 4 5 4 5 4 5))))
             (array-set! a 4 4 4 "huuhkaja")
             (array-ref a 4 4 4))
     Returns ‘"huuhkaja"’.

     _Compatibility:_ SRFI-47, Guile and Scheme-48 have ‘array-set!’
     with a different argument order.

 -- Procedure: array-copy! dst src
     _Compatibility:_ Guile has a ‘array-copy!’ with the reversed
     argument order.

 -- Procedure: array-fill! array value
     Set all the values ARRAY to VALUE.

14.8.7 Transformations and views
--------------------------------

A view or transform of an array is an array A_{2} whose elements come
from some other array A_{1}, given some transform function T that maps
A_{2} indexes to A_{1} indexes.  Specifically ‘(array-ref A_{2}
INDEXES)’ is ‘(array-ref A_{1} (T INDEXES))’.  Modifying A_{2} causes
A_{1} to be modified; modifying A_{1} may modify A_{2} (depending on the
transform function).  The shape of A_{2} is in generally different than
that of A_{1}.

 -- Procedure: array-transform array shape transform
     This is a general mechanism for creating a view.  The result is a
     new array with the given SHAPE.  Accessing this new array is
     implemented by calling the TRANSFORM function on the index vector,
     which must return a new index vector valid for indexing the
     original ARRAY.  Here is an example (using the same ‘arr’ as in the
     ‘array-index-ref’ example):
          #|kawa:1|# (define arr (array #2a((1 4) (0 4))
          #|.....2|#                    10 11 12 13 20 21 22 23 30 31 32 33))
          #|kawa:14|# (array-transform arr #2a((0 3) (1 3) (0 2))
          #|.....15|#   (lambda (ix) (let ((i (ix 0)) (j (ix 1)) (k (ix 2)))
          #|.....16|#                  [(+ i 1)
          #|.....17|#                   (+ (* 2 (- j 1)) k)])))
          #3a:3@1:2:2
          ║10│11║
          ╟──┼──╢
          ║12│13║
          ╠══╪══╣
          ║20│21║
          ╟──┼──╢
          ║22│23║
          ╠══╪══╣
          ║30│31║
          ╟──┼──╢
          ║32│33║
          ╚══╧══╝

     The ‘array-transform’ is generalization of ‘share-array’, in that
     it does not require the TRANSFORM to be affine.  Also note the
     different calling conversions for the TRANFORM: ‘array-transform’
     takes a single argument (a vector of indexes), and returns a single
     result (a vector of indexes); ‘share-array’ takes one argument for
     each index, and returns one value for each index.  The difference
     is historical.

 -- Procedure: array-index-share array index ...
     This does the same generalized APL-style indexing as
     ‘array-index-ref’.  However, the resulting array is a modifiable
     view into the argument ARRAY.

 -- Procedure: array-reshape array shape
     Creates a new array NARRAY of the given SHAPE, such that
     ‘(array->vector ARRAY)’ and ‘(array->vector NARRAY)’ are
     equivalent.  I.e.  the I’th element in row-major-order of NARRAY is
     the I’th element in row-major-order of ARRAY.  Hence ‘(array-size
     NARRAY)’ (as specied from the SHAPE) must be equal to ‘(array-size
     ARRAY)’.  The resulting NARRAY is a view such that modifying ARRAY
     also modifies NARRAY and vice versa.

 -- Procedure: share-array array shape proc
     Returns a new array of SHAPE shape that shares elements of ARRAY
     through PROC.  The procedure PROC must implement an affine function
     that returns indices of ARRAY when given indices of the array
     returned by ‘share-array’.  The array does not retain a reference
     to SHAPE.
          (define i_4
             (let* ((i (make-array
                          (shape 0 4 0 4)
                          0))
                    (d (share-array i
                          (shape 0 4)
                          (lambda (k)
                             (values k k)))))
                (do ((k 0 (+ k 1)))
                    ((= k 4))
                   (array-set! d k 1))
                i))

     Note: the affinity requirement for PROC means that each value must
     be a sum of multiples of the arguments passed to PROC, plus a
     constant.

     Implementation note: arrays have to maintain an internal index
     mapping from indices K1 ...  KD to a single index into a backing
     vector; the composition of this mapping and PROC can be recognised
     as ‘(+ N0 (* N1 K1) ... (* ND KD))’ by setting each index in turn
     to 1 and others to 0, and all to 0 for the constant term; the
     composition can then be compiled away, together with any complexity
     that the user introduced in their procedure.

     Here is an example where the ARRAY is a uniform vector:
          (share-array
            (f64vector 1.0 2.0 3.0 4.0 5.0 6.0)
            (shape 0 2 0 3)
            (lambda (i j) (+ (* 2 i) j)))
            ⇒  #2f64((1.0 2.0 3.0) (4.0 5.0 6.0))

 -- Procedure: array-flatten array
 -- Procedure: array->vector array
     Return a vector consisting of the elements of the ARRAY in
     row-major-order.

     The result of ‘array-flatten’ is fresh (mutable) copy, not a view.
     The result of ‘array->vector’ is a view: If ARRAY is mutable, then
     modifying ARRAY changes the flattened result and vice versa.

     If ARRAY is “simple”, ‘array->vector’ returns the original vector.
     Specifically, if VEC is a vector then:
          (eq? VEC (array->vector (array-reshape VEC SHAPE)))

14.8.8 Miscellaneous
--------------------

 -- Procedure: format-array value [element-format]


File: kawa.info,  Node: Hash tables,  Prev: Arrays,  Up: Data structures

14.9 Hash tables
================

A “hashtable” is a data structure that associates keys with values.  The
hashtable has no intrinsic order for the (key, value) associations it
contains, and supports in-place modification as the primary means of
setting the contents of a hash table.  Any object can be used as a key,
provided a “hash function” and a suitable “equivalence function” is
available.  A hash function is a procedure that maps keys to exact
integer objects.

   The hashtable provides key lookup and destructive update in amortised
constant time, provided that a good hash function is used.  A hash
function H is acceptable for an equivalence predicate E iff ‘(E OBJ1
OBJ2)’ implies ‘(= (H OBJ1) (H OBJ2))’.  A hash function H is good for a
equivalence predicate E if it distributes the resulting hash values for
non-equal objects (by E) as uniformly as possible over the range of hash
values, especially in the case when some (non-equal) objects resemble
each other by e.g.  having common subsequences.  This definition is
vague but should be enough to assert that e.g.  a constant function is
not a good hash function.

   Kawa provides two complete sets of functions for hashtables:
   • The functions specified by R6RS have names starting with
     ‘hashtable-’
   • The functions specified by the older SRFI-69
     (http://srfi.schemers.org/srfi-69/srfi-69.html) specifiation have
     names starting with ‘hash-table-’

   Both interfaces use the same underlying datatype, so it is possible
to mix and match from both sets.  That datatype implements
‘java.util.Map’.  Freshly-written code should probably use the R6RS
functions.

14.9.1 R6RS hash tables
-----------------------

To use these hash table functions in your Kawa program you must first:

     (import (rnrs hashtables))

   This section uses the HASHTABLE parameter name for arguments that
must be hashtables, and the KEY parameter name for arguments that must
be hashtable keys.

 -- Procedure: make-eq-hashtable
 -- Procedure: make-eq-hashtable K
     Return a newly allocated mutable hashtable that accepts arbitrary
     objects as keys, and compares those keys with ‘eq?’.  If an
     argument is given, the initial capacity of the hashtable is set to
     approximately K elements.

 -- Procedure: make-eqv-hashtable
 -- Procedure: make-eqv-hashtable K
     Return a newly allocated mutable hashtable that accepts arbitrary
     objects as keys, and compares those keys with ‘eqv?’.  If an
     argument is given, the initial capacity of the hashtable is set to
     approximately K elements.

 -- Procedure: make-hashtable HASH-FUNCTION EQUIV
 -- Procedure: make-hashtable HASH-FUNCTION EQUIV K
     HASH-FUNCTION and EQUIV must be procedures.  HASH-FUNCTION should
     accept a key as an argument and should return a non–negative exact
     integer object.  EQUIV should accept two keys as arguments and
     return a single value.  Neither procedure should mutate the
     hashtable returned by ‘make-hashtable’.

     The ‘make-hashtable’ procedure returns a newly allocated mutable
     hashtable using HASH-FUNCTION as the hash function and EQUIV as the
     equivalence function used to compare keys.  If a third argument is
     given, the initial capacity of the hashtable is set to
     approximately K elements.

     Both HASH-FUNCTION and EQUIV should behave like pure functions on
     the domain of keys.  For example, the ‘string-hash’ and ‘string=?’
     procedures are permissible only if all keys are strings and the
     contents of those strings are never changed so long as any of them
     continues to serve as a key in the hashtable.  Furthermore, any
     pair of keys for which EQUIV returns true should be hashed to the
     same exact integer objects by HASH-FUNCTION.

          _Note:_ Hashtables are allowed to cache the results of calling
          the hash function and equivalence function, so programs cannot
          rely on the hash function being called for every lookup or
          update.  Furthermore any hashtable operation may call the hash
          function more than once.

14.9.1.1 Procedures
...................

 -- Procedure: hashtable? OBJ
     Return ‘#t’ if OBJ is a hashtable, ‘#f’ otherwise.

 -- Procedure: hashtable-size HASHTABLE
     Return the number of keys contained in HASHTABLE as an exact
     integer object.

 -- Procedure: hashtable-ref HASHTABLE KEY DEFAULT
     Return the value in HASHTABLE associated with KEY.  If HASHTABLE
     does not contain an association for KEY, DEFAULT is returned.

 -- Procedure: hashtable-set! HASHTABLE KEY OBJ
     Change HASHTABLE to associate KEY with OBJ, adding a new
     association or replacing any existing association for KEY, and
     returns unspecified values.

 -- Procedure: hashtable-delete! HASHTABLE KEY
     Remove any association for KEY within HASHTABLE and returns
     unspecified values.

 -- Procedure: hashtable-contains? HASHTABLE KEY
     Return ‘#t’ if HASHTABLE contains an association for KEY, ‘#f’
     otherwise.

 -- Procedure: hashtable-update! HASHTABLE KEY PROC DEFAULT
     PROC should accept one argument, should return a single value, and
     should not mutate HASHTABLE.

     The ‘hashtable-update!’ procedure applies PROC to the value in
     HASHTABLE associated with KEY, or to DEFAULT if HASHTABLE does not
     contain an association for KEY.  The HASHTABLE is then changed to
     associate KEY with the value returned by PROC.

     The behavior of ‘hashtable-update!’ is equivalent to the following
     code, but is may be (and is in Kawa) implemented more efficiently
     in cases where the implementation can avoid multiple lookups of the
     same key:

          (hashtable-set!
            hashtable key
            (proc (hashtable-ref
                   hashtable key default)))

 -- Procedure: hashtable-copy HASHTABLE
 -- Procedure: hashtable-copy HASHTABLE MUTABLE
     Return a copy of HASHTABLE.  If the MUTABLE argument is provided
     and is true, the returned hashtable is mutable; otherwise it is
     immutable.

 -- Procedure: hashtable-clear! HASHTABLE
 -- Procedure: hashtable-clear! HASHTABLE K
     Remove all associations from HASHTABLE and returns unspecified
     values.

     If a second argument is given, the current capacity of the
     hashtable is reset to approximately K elements.

 -- Procedure: hashtable-keys HASHTABLE
     Return a vector of all keys in HASHTABLE.  The order of the vector
     is unspecified.

 -- Procedure: hashtable-entries HASHTABLE
     Return two values, a vector of the keys in HASHTABLE, and a vector
     of the corresponding values.

     Example:

          (let ((h (make-eqv-hashtable)))
            (hashtable-set! h 1 'one)
            (hashtable-set! h 2 'two)
            (hashtable-set! h 3 'three)
            (hashtable-entries h))
          ⇒ #(1 2 3) #(one two three) ; two return values

     the order of the entries in the result vectors is not known.

14.9.1.2 Inspection
...................

 -- Procedure: hashtable-equivalence-function HASHTABLE
     Return the equivalence function used by HASHTABLE to compare keys.
     For hashtables created with ‘make-eq-hashtable’ and
     ‘make-eqv-hashtable’, returns ‘eq?’ and ‘eqv?’ respectively.

 -- Procedure: hashtable-hash-function HASHTABLE
     Return the hash function used by HASHTABLE.  For hashtables created
     by ‘make-eq-hashtable’ or ‘make-eqv-hashtable’, ‘#f’ is returned.

 -- Procedure: hashtable-mutable? HASHTABLE
     Return ‘#t’ if HASHTABLE is mutable, otherwise ‘#f’.

14.9.1.3 Hash functions
.......................

The ‘equal-hash’, ‘string-hash’, and ‘string-ci-hash’ procedures of this
section are acceptable as the hash functions of a hashtable only if the
keys on which they are called are not mutated while they remain in use
as keys in the hashtable.

 -- Procedure: equal-hash OBJ
     Return an integer hash value for OBJ, based on its structure and
     current contents.  This hash function is suitable for use with
     ‘equal?’ as an equivalence function.
          _Note:_ Like ‘equal?’, the ‘equal-hash’ procedure must always
          terminate, even if its arguments contain cycles.

 -- Procedure: string-hash STRING
     Return an integer hash value for STRING, based on its current
     contents.  This hash function is suitable for use with ‘string=?’
     as an equivalence function.

 -- Procedure: string-ci-hash STRING
     Return an integer hash value for STRING based on its current
     contents, ignoring case.  This hash function is suitable for use
     with ‘string-ci=?’ as an equivalence function.

 -- Procedure: symbol-hash SYMBOL
     Return an integer hash value for SYMBOL.

14.9.2 SRFI-69 hash tables
--------------------------

To use these hash table functions in your Kawa program you must first:
     (require 'srfi-69)
   or
     (require 'hash-table)
   or
     (import (srfi 69 basic-hash-tables))

14.9.2.1 Type constructors and predicate
........................................

 -- Procedure: make-hash-table [ equal? [ hash [ size-hint]]] →
          hash-table

     Create a new hash table with no associations.  The EQUAL? parameter
     is a predicate that should accept two keys and return a boolean
     telling whether they denote the same key value; it defaults to the
     ‘equal?’ function.

     The HASH parameter is a hash function, and defaults to an
     appropriate hash function for the given EQUAL? predicate (see the
     Hashing section).  However, an acceptable default is not guaranteed
     to be given for any equivalence predicate coarser than ‘equal?’,
     except for ‘string-ci=?’.  (The function ‘hash’ is acceptable for
     ‘equal?’, so if you use coarser equivalence than ‘equal?’ other
     than ‘string-ci=?’, you must always provide the function hash
     yourself.)  (An equivalence predicate C1 is coarser than a
     equivalence predicate C2 iff there exist values X and Y such that
     ‘(and (C1 X Y) (not (C2 X Y)))’.)

     The SIZE-HINT parameter can be used to suggested an approriate
     initial size.  This option is not part of the SRFI-69 specification
     (though it is handled by the reference implementation), so
     specifying that option might be unportable.

 -- Procedure: hash-table? obj → boolean
     A predicate to test whether a given object OBJ is a hash table.

 -- Procedure: alist->hash-table alist [ equal? [ hash [ size-hint]]] →
          hash-table

     Takes an association list ALIST and creates a hash table HASH-TABLE
     which maps the ‘car’ of every element in ALIST to the ‘cdr’ of
     corresponding elements in ALIST.  The EQUAL?, HASH, and SIZE-HINT
     parameters are interpreted as in ‘make-hash-table’.  If some key
     occurs multiple times in ALIST, the value in the first association
     will take precedence over later ones.  (Note: the choice of using
     ‘cdr’ (instead of ‘cadr’) for values tries to strike balance
     between the two approaches: using CADR would render this procedure
     unusable for ‘cdr’ alists, but not vice versa.)

14.9.2.2 Reflective queries
...........................

 -- Procedure: hash-table-equivalence-function hash-table
     Returns the equivalence predicate used for keys of HASH-TABLE.

 -- Procedure: hash-table-hash-function hash-table
     Returns the hash function used for keys of HASH-TABLE.

14.9.2.3 Dealing with single elements
.....................................

 -- Procedure: hash-table-ref hash-table key [ thunk ] → value
     This procedure returns the value associated to KEY in HASH-TABLE.
     If no value is associated to KEY and THUNK is given, it is called
     with no arguments and its value is returned; if THUNK is not given,
     an error is signalled.  Given a good hash function, this operation
     should have an (amortised) complexity of O(1) with respect to the
     number of associations in HASH-TABLE.

 -- Procedure: hash-table-ref/default hash-table key default → value
     Evaluates to the same value as ‘(hash-table-ref HASH-TABLE KEY
     (lambda () DEFAULT))’.  Given a good hash function, this operation
     should have an (amortised) complexity of O(1) with respect to the
     number of associations in hash-table.

 -- Procedure: hash-table-set! hash-table key value → void
     This procedure sets the value associated to KEY in HASH-TABLE.  The
     previous association (if any) is removed.  Given a good hash
     function, this operation should have an (amortised) complexity of
     O(1) with respect to the number of associations in hash-table.

 -- Procedure: hash-table-delete! hash-table key → void
     This procedure removes any association to KEY in HASH-TABLE.  It is
     not an error if no association for the KEY exists; in this case,
     nothing is done.  Given a good hash function, this operation should
     have an (amortised) complexity of O(1) with respect to the number
     of associations in hash-table.

 -- Procedure: hash-table-exists? hash-table key → boolean
     This predicate tells whether there is any association to KEY in
     HASH-TABLE.  Given a good hash function, this operation should have
     an (amortised) complexity of O(1) with respect to the number of
     associations in hash-table.

 -- Procedure: hash-table-update! hash-table key function [ thunk ] →
          void
     Semantically equivalent to, but may be implemented more efficiently
     than, the following code:
          (hash-table-set! HASH-TABLE KEY
                           (function (hash-table-ref HASH-TABLE KEY THUNK)))

 -- Procedure: hash-table-update!/default hash-table key function
          default → void
     Behaves as if it evaluates to ‘(hash-table-update! HASH-TABLE KEY
     FUNCTION (lambda () DEFAULT))’.

14.9.2.4 Dealing with the whole contents
........................................

 -- Procedure: hash-table-size hash-table → integer
     Returns the number of associations in HASH-TABLE.  This operation
     takes constant time.

 -- Procedure: hash-table-keys hash-table → list
     Returns a list of keys in HASH-TABLE.  The order of the keys is
     unspecified.

 -- Procedure: hash-table-values hash-table → list
     Returns a list of values in HASH-TABLE.  The order of the values is
     unspecified, and is not guaranteed to match the order of keys in
     the result of ‘hash-table-keys’.

 -- Procedure: hash-table-walk hash-table proc → void
     PROC should be a function taking two arguments, a key and a value.
     This procedure calls PROC for each association in HASH-TABLE,
     giving the key of the association as key and the value of the
     association as value.  The results of PROC are discarded.  The
     order in which PROC is called for the different associations is
     unspecified.

 -- Procedure: hash-table-fold hash-table f init-value → final-value
     This procedure calls F for every association in HASH-TABLE with
     three arguments: the key of the association key, the value of the
     association value, and an accumulated value, VAL.  The VAL is
     INIT-VALUE for the first invocation of F, and for subsequent
     invocations of F, the return value of the previous invocation of F.
     The value FINAL-VALUE returned by ‘hash-table-fold’ is the return
     value of the last invocation of F.  The order in which F is called
     for different associations is unspecified.

 -- Procedure: hash-table->alist hash-table → alist
     Returns an association list such that the ‘car’ of each element in
     ALIST is a key in HASH-TABLE and the corresponding ‘cdr’ of each
     element in ALIST is the value associated to the key in HASH-TABLE.
     The order of the elements is unspecified.

     The following should always produce a hash table with the same
     mappings as a hash table H:
          (alist->hash-table (hash-table->alist H)
                                  (hash-table-equivalence-function H)
                                  (hash-table-hash-function H))

 -- Procedure: hash-table-copy hash-table → hash-table
     Returns a new hash table with the same equivalence predicate, hash
     function and mappings as in HASH-TABLE.

 -- Procedure: hash-table-merge! hash-table1 hash-table2 → hash-table
     Adds all mappings in HASH-TABLE2 into HASH-TABLE1 and returns the
     resulting hash table.  This function may modify HASH-TABLE1
     destructively.

14.9.2.5 Hash functions
.......................

The Kawa implementation always calls these hash functions with a single
parameter, and expects the result to be within the entire (32-bit
signed) ‘int’ range, for compatibility with standard ‘hashCode’ methods.

 -- Procedure: hash object [ bound ] → integer
     Produces a hash value for object in the range from 0 (inclusive) tp
     to BOUND (exclusive).

     If BOUND is not given, the Kawa implementation returns a value
     within the range ‘(- (expt 2 32))’ (inclusive) to
     ‘(- (expt 2 32) 1)’ (inclusive).  It does this by calling the
     standard ‘hashCode’ method, and returning the result as is.  (If
     the OBJECT is the Java ‘null’ value, 0 is returned.)  This hash
     function is acceptable for ‘equal?’.

 -- Procedure: string-hash string [ bound ] → integer
     The same as ‘hash’, except that the argument string must be a
     string.  (The Kawa implementation returns the same as the ‘hash’
     function.)

 -- Procedure: string-ci-hash string [ bound ] → integer
     The same as ‘string-hash’, except that the case of characters in
     string does not affect the hash value produced.  (The Kawa
     implementation returns the same the ‘hash’ function applied to the
     lower-cased STRING.)

 -- Procedure: hash-by-identity object [ bound ] → integer
     The same as ‘hash’, except that this function is only guaranteed to
     be acceptable for ‘eq?’.  Kawa uses the ‘identityHashCode’ method
     of ‘java.lang.System’.


File: kawa.info,  Node: Eval and Environments,  Next: Debugging,  Prev: Data structures,  Up: Top

15 Eval and Environments
************************

 -- Procedure: environment list^{*}
     This procedure returns a specifier for the environment that results
     by starting with an empty environment and then importing each LIST,
     considered as an IMPORT-SET, into it.  The bindings of the
     environment represented by the specifier are immutable, as is the
     environment itself.  See the ‘eval’ function for examples.

 -- Procedure: null-environment version
     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.

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

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

 -- Procedure: environment-bound? environment symbol
     Return true ‘#t’ if there is a binding for SYMBOL in ENVIRONMENT;
     otherwise returns ‘#f’.

 -- Procedure: environment-fold environment proc init
     Call PROC for each key in the ENVIRONMENT, which may be any
     argument to ‘eval’, such as ‘(interaction-environment)’ or a call
     to the ‘environment’ procedure.  The PROC is called with two
     arguments: The binding’s key, and an accumulator value.  The INIT
     is the initial accumulator value; the result returned by PROC is
     used for subsequent accumulator values.  The value returned by
     ‘environment-fold’ is the final acumulator value.

     A key is normally a symbol, but can also be a ‘KeyPair’ object (a
     pair of a symbol and a property symbol used to implement Common
     Lisp-style property lists).
          (environment-fold (environment '(scheme write)) cons '())
            ⇒ (display write-shared write write-simple)
     To get all the predefined bindings use ‘(environment '(kawa
     base))’.

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

 -- Procedure: base-uri [node]
     If NODE is specified, returns the base-URI property of the NODE.
     If the NODE does not have the base-URI property, returns ‘#f’.
     (The XQuery version returns the empty sequence in that case.)

     In the zero-argument case, returns the "base URI" of the current
     context.  By default the base URI is the current working directory
     (as a URL). While a source file is ‘load’ed, the base URI is
     temporarily set to the URL of the document.

 -- Procedure: eval expression [environment]
     This procedure evaluates EXPRESSION in the environment indicated by
     ENVIRONMENT.  The default for ENVIRONMENT is the result of
     ‘(interaction-environment)’.

          (eval ’(* 7 3) (environment '(scheme base)))
                      ⇒ 21

          (let ((f (eval '(lambda (f x) (f x x))
                         (null-environment 5))))
            (f + 10))
                      ⇒ 20

          (eval '(define foo 32) (environment '(scheme base)))
                      ⇒ error is signaled

 -- Procedure: load path [environment]
 -- Procedure: load-relative path [environment]
     The PATH can be an (absolute) URL or a filename of a source file,
     which is read and evaluated line-by-line.  The PATH can also be a
     fully-qualified class name.  (Mostly acts like the ‘-f’
     command-line option, but with different error handling.)  Since
     ‘load’ is a run-time function it doesn’t know about the enclosing
     lexical environment, and the latter can’t know about definitions
     introduced by ‘load’.  For those reasons it is highly recommended
     that you use instead use ‘*note require: require.’ or ‘*note
     include: include.’.

     Evaluation is done in the specified ENVIRONMENT, which defauls to
     result of ‘(interaction-environment)’.

     The ‘load-relative’ procedure is like ‘load’, except that PATH is a
     URI that is relative to the context’s current base URI.

* Menu:

* Locations::
* Parameter objects::


File: kawa.info,  Node: Locations,  Next: Parameter objects,  Up: Eval and Environments

15.1 Locations
==============

A “location” is a place where a value can be stored.  An “lvalue” is an
expression that refers to a location.  (The name "lvalue" refers to the
fact that the left operand of ‘set!’ is an lvalue.)  The only kind of
lvalue in standard Scheme is a “variable”.  Kawa also allows “computed
lvalues”.  These are procedure calls used in "lvalue context", such as
the left operand of ‘set!’.

   You can only use procedures that have an associated “setter”.  In
that case, ‘(set! (f arg ...) value)’ is equivalent to ‘((setter f) arg
... value)’ Currently, only a few procedures have associated ‘setter’s,
and only builtin procedures written in Java can have ‘setter’s.

   For example:
     (set! (car x) 10)
   is equivalent to:
     ((setter car) x 10)
   which is equivalent to:
     (set-car! x 10)

 -- Procedure: setter procedure
     Gets the "setter procedure" associated with a "getter procedure".
     Equivalent to ‘(procedure-property PROCEDURE 'setter)’.  By
     convention, a setter procedure takes the same parameters as the
     "getter" procedure, plus an extra parameter that is the new value
     to be stored in the location specified by the parameters.  The
     expectation is that following ‘((setter PROC) ARGS ... VALUE)’ then
     the value of ‘(PROC ARGS ...)’ will be VALUE.

     The ‘setter’ of ‘setter’ can be used to set the ‘setter’ property.
     For example the Scheme prologue effectively does the following:
          (set! (setter vector-set) vector-set!)

   Kawa also gives you access to locations as first-class values:

 -- Syntax: location lvalue
     Returns a location object for the given LVALUE.  You can get its
     value (by applying it, as if it were a procedure), and you can set
     its value (by using ‘set!’ on the application).  The LVALUE can be
     a local or global variable, or a procedure call using a procedure
     that has a ‘setter’.
          (define x 100)
          (define lx (location x))
          (set! (lx) (cons 1 2)) ;; set x to (1 . 2)
          (lx)  ;; returns (1 . 2)
          (define lc (location (car x)))
          (set! (lc) (+ 10 (lc)))
          ;; x is now (11 . 2)

 -- Syntax: define-alias variable lvalue
     Define VARIABLE as an alias for LVALUE.  In other words, makes it
     so that ‘(location VARIABLE)’ is equivalent to ‘(location LVALUE)’.
     This works both top-level and inside a function.

 -- Syntax: define-private-alias variable lvalue
     Same as ‘define-alias’, but the VARIABLE is local to the current
     module.

   Some people might find it helpful to think of a location as a
settable “thunk”.  Others may find it useful to think of the ‘location’
syntax as similar to the C ‘&’ operator; for the ‘*’ indirection
operator, Kawa uses procedure application.

   You can use ‘define-alias’ to define a shorter type synonym, similar
to Java’s ‘import TypeName’ (single-type-import) declaration:
     (define-alias StrBuf java.lang.StringBuffer)


File: kawa.info,  Node: Parameter objects,  Prev: Locations,  Up: Eval and Environments

15.2 Parameter objects
======================

A parameter object is a procedure that is bound to a location, and may
optionally have a conversion procedure.  The procedure accepts zero or
one argument.  When the procedure is called with zero arguments, the
content of the location is returned.  On a call with one argument the
content of the location is updated with the result of applying the
parameter object’s conversion procedure to the argument.

   Parameter objects are created with the ‘make-parameter’ procedure
which takes one or two arguments.  The second argument is a one argument
conversion procedure.  If only one argument is passed to make-parameter
the identity function is used as a conversion procedure.  A new location
is created and asociated with the parameter object.  The initial content
of the location is the result of applying the conversion procedure to
the first argument of make-parameter.

   Note that the conversion procedure can be used for guaranteeing the
type of the parameter object’s binding and/or to perform some conversion
of the value.

   The ‘parameterize’ special form, when given a parameter object and a
value, binds the parameter object to a new location for the dynamic
extent of its body.  The initial content of the location is the result
of applying the parameter object’s conversion procedure to the value.
The ‘parameterize’ special form behaves analogously to ‘let’ when
binding more than one parameter object (that is the order of evaluation
is unspecified and the new bindings are only visible in the body of the
parameterize special form).

   When a new thread is created using ‘future’ or ‘runnable’ then the
child thread inherits initial values from its parent.  Once the child is
running, changing the value in the child does not affect the value in
the parent or vice versa.  (In the past this was not the case: The child
would share a location with the parent except within a ‘parameterize’.
This was changed to avoid unsafe and inefficient coupling between
threads.)

   Note that ‘parameterize’ and ‘fluid-let’ have similar binding and
sharing behavior.  The difference is that ‘fluid-let’ modifies locations
accessed by name, while ‘make-parameter’ and ‘parameterize’ create
anonymous locations accessed by calling a parameter procedure.

   The R5RS procedures ‘current-input-port’ and ‘current-output-port’
are parameter objects.

 -- Procedure: make-parameter init [converter]

     Returns a new parameter object which is bound in the global dynamic
     environment to a location containing the value returned by the call
     ‘(CONVERTER INIT)’.  If the conversion procedure converter is not
     specified the identity function is used instead.

     The parameter object is a procedure which accepts zero or one
     argument.  When it is called with no argument, the content of the
     location bound to this parameter object in the current dynamic
     environment is returned.  When it is called with one argument, the
     content of the location is set to the result of the call
     ‘(CONVERTER ARG)’, where ARG is the argument passed to the
     parameter object, and an unspecified value is returned.

          (define radix
            (make-parameter 10))

          (define write-shared
            (make-parameter
              #f
              (lambda (x)
                (if (boolean? x)
                    x
                    (error "only booleans are accepted by write-shared")))))

          (radix)           ⇒  10
          (radix 2)
          (radix)           ⇒  2
          (write-shared 0)  gives an error

          (define prompt
            (make-parameter
              123
              (lambda (x)
                (if (string? x)
                    x
                    (with-output-to-string (lambda () (write x)))))))

          (prompt)       ⇒  "123"
          (prompt ">")
          (prompt)       ⇒  ">"

 -- Syntax: parameterize ((expr1 expr2) ...) BODY
     The expressions EXPR1 and EXPR2 are evaluated in an unspecified
     order.  The value of the EXPR1 expressions must be parameter
     objects.  For each EXPR1 expression and in an unspecified order,
     the local dynamic environment is extended with a binding of the
     parameter object EXPR1 to a new location whose content is the
     result of the call ‘(CONVERTER VAL)’, where VAL is the value of
     EXPR2 and CONVERTER is the conversion procedure of the parameter
     object.  The resulting dynamic environment is then used for the
     evaluation of BODY (which refers to the R5RS grammar nonterminal of
     that name).  The result(s) of the parameterize form are the
     result(s) of the BODY.

          (radix)                                              ⇒  2
          (parameterize ((radix 16)) (radix))                  ⇒  16
          (radix)                                              ⇒  2

          (define (f n) (number->string n (radix)))

          (f 10)                                               ⇒  "1010"
          (parameterize ((radix 8)) (f 10))                    ⇒  "12"
          (parameterize ((radix 8) (prompt (f 10))) (prompt))  ⇒  "1010"


File: kawa.info,  Node: Debugging,  Next: Input-Output,  Prev: Eval and Environments,  Up: Top

16 Debugging
************

 -- Syntax: trace procedure
     Cause PROCEDURE to be "traced", that is debugging output will be
     written to the standard error port every time PROCEDURE is called,
     with the parameters and return value.

     Note that Kawa will normally assume that a procedure defined with
     the procedure-defining variant of ‘define’ is constant, and so it
     might be inlined:
          (define (ff x) (list x x))
          (trace ff) ;; probably won't work
          (ff 3)     ;; not traced
     It works if you specify the ‘--no-inline’ flag to Kawa.
     Alternatively, you can use the variable-defining variant of
     ‘define’:
          #|kawa:1|# (define ff (lambda (x) name: 'ff (list x x)))
          #|kawa:2|# (trace ff) ;; works
          #|kawa:3|# (ff 3)
          call to ff (3)
          return from ff => (3 3)
          (3 3)
     Note the use of the ‘name:’ procedure property to give the
     anonymous ‘lambda’ a name.

 -- Syntax: untrace procedure
     Turn off tracing (debugging output) of PROCEDURE.

 -- Procedure: disassemble procedure
     Returns a string representation of the disassembled bytecode for
     PROCEDURE, when known.


File: kawa.info,  Node: Input-Output,  Next: Types,  Prev: Debugging,  Up: Top

17 Input, output, and file handling
***********************************

Kawa has a number of useful tools for controlling input and output:

   A programmable reader.

   A powerful pretty-printer.

* Menu:

* Named output formats::
* Paths:: Paths - file name, URLs, and URIs
* Files:: File System Interface
* Reading and writing whole files::
* Ports::
* Format:: Formatted Output (Common-Lisp-style)
* Pretty-printing::
* Resources::


File: kawa.info,  Node: Named output formats,  Next: Paths,  Up: Input-Output

17.1 Named output formats
=========================

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 just a script name).  (It also affects applications
compiled with the ‘--main’ flag.)  It currently affects 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’
‘xhtml’
‘html’
     Values are printed in XML, XHTML, or HTML format.  This is
     discussed in more detail in *note Formatting XML::.
‘cgi’
     The output should 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-type’ depending
     on the following value.
‘ignore’
     Top-level values are ignored, instead of printed.


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

17.2 Paths - file name, URLs, and URIs
======================================

A “Path” is the name of a file or some other “resource”.  The path
mechanism provides a layer of abstraction, so you can use the same
functions on either a filename or a URL/URI. Functions that in standard
Scheme take a filename have been generalized to take a path or a path
string, as if using the ‘path’ function below.  For example:
     (open-input-file "http://www.gnu.org/index.html")
     (open-input-file (URI "ftp://ftp.gnu.org/README"))

 -- Type: path
     A general path, which can be a ‘filename’ or a ‘URI’.  It can be
     either a ‘filename’ or a ‘URI’.  Represented using the abstract
     Java class ‘gnu.kawa.io.Path’.

     Coercing a value to a ‘Path’ is equivalent to calling the ‘path’
     constructor documented below.

 -- Constructor: path arg
     Coerces the ARG to a ‘path’.  If ARG is already a ‘path’, it is
     returned unchanged.  If ARG is a ‘java.net.URI’, or a
     ‘java.net.URL’ then a ‘URI’ value is returned.  If ARG is a
     ‘java.io.File’, a ‘filepath’ value is returned.  Otherwise, ARG can
     be a string.  A ‘URI’ value is returned if the string starts with a
     URI scheme (such as ‘"http:"’), and a ‘filepath’ value is returned
     otherwise.

 -- Predicate: path? arg
     True if ARG is a ‘path’ - i.e.  an instance of a
     ‘gnu.kawa.io.Path’.

 -- Procedure: current-path [new-value]
     With no arguments, returns the default directory of the current
     thread as a ‘path’.  This is used as the base directory for
     relative pathnames.  The initial value is that of the ‘user.dir’
     property as returned by ‘(java.lang.System:getProperty
     "user.dir")’.

     If a NEW-VALUE argument is given, sets the default directory:
          (current-path "/opt/myApp/")
     A string value is automatically converted to a ‘path’, normally a
     ‘filepath’.

     Alternatively, you can change the default using a setter:
          (set! (current-path) "/opt/myApp/")

     Since ‘current-path’ is a *note parameter object: Parameter
     objects, you can locally change the value using *note
     ‘parameterize’: parameterize-syntax.

 -- Type: filepath
     The name of a local file.  Represented using the Java class
     ‘gnu.kawa.io.FilePath’, which is a wrapper around ‘java.io.File’.

 -- Predicate: filepath? arg
     True if ARG is a ‘filepath’ - i.e.  an instance of a
     ‘gnu.kawa.io.FilePath’.

 -- Type: URI
     A Uniform Resource Indicator, which is a generalization of the more
     familiar URL. The general format is specified by RFC 2396: Uniform
     Resource Identifiers (URI): Generic Syntax
     (http://www.ietf.org/rfc/rfc2396.txt).  Represented using the Java
     class ‘gnu.kawa.io.URIPath’, which is a wrapper around
     ‘java.net.URI’.  A URI can be a URL, or it be a relative URI.

 -- Predicate: URI? arg
     True if ARG is a ‘URI’ - i.e.  an instance of a
     ‘gnu.kawa.io.URIPath’.

 -- Type: URL
     A Uniform Resource Locator - a subtype of ‘URI’.  Represented using
     the Java class ‘gnu.kawa.io.URLPath’, which is a wrapper around a
     ‘java.net.URL’, in addition to extending ‘gnu.kawa.io.URIPath’.

17.2.1 Extracting Path components
---------------------------------

 -- Procedure: path-scheme arg
     Returns the “URI scheme” of ARG (coerced to a ‘path’) if it is
     defined, or ‘#f’ otherwise.  The URI scheme of a ‘filepath’ is
     ‘"file"’ if the ‘filepath’ is absolute, and ‘#f’ otherwise.
          (path-scheme "http://gnu.org/") ⇒ "http"

 -- Procedure: path-authority arg
     Returns the authority part of ARG (coerced to a ‘path’) if it is
     defined, or ‘#f’ otherwise.  The “authority” is usually the
     hostname, but may also include user-info or a port-number.

          (path-authority "http://me@localhost:8000/home") ⇒ "me@localhost:8000"

 -- Procedure: path-host arg
     Returns the name name part of ARG (coerced to a ‘path’) if it is
     defined, or ‘#f’ otherwise.

          (path-host "http://me@localhost:8000/home") ⇒ "localhost"

 -- Procedure: path-user-info arg
     Returns the “user info” of ARG (coerced to a ‘path’) if it is
     specified, or ‘#f’ otherwise.

          (path-host "http://me@localhost:8000/home") ⇒ "me"

 -- Procedure: path-port arg
     Returns the port number of ARG (coerced to a ‘path’) if it is
     specified, or ‘-1’ otherwise.  Even if there is a default port
     associated with a URI scheme (such as 80 for ‘http’), the value -1
     is returned unless the port number is _explictly_ specified.

          (path-host "http://me@localhost:8000/home") ⇒ 8000
          (path-host "http://me@localhost/home") ⇒ -1

 -- Procedure: path-file arg
     Returns the “path component” of the ARG (coerced to a ‘path’).
     (The name ‘path-path’ might be more logical, but it is obviously a
     bit awkward.)  The path component of a file name is the file name
     itself.  For a URI, it is the main hierarchical part of the URI,
     without schema, authority, query, or fragment.
          (path-file "http://gnu.org/home/me.html?add-bug#body") ⇒ "/home/me.html"

 -- Procedure: path-directory arg
     If ARG (coerced to a ‘path’) is directory, return ARG; otherwise
     return the “parent” path, without the final component.
          (path-directory "http://gnu.org/home/me/index.html#body")
            ⇒ (path "http://gnu.org/home/me/")
          (path-directory "http://gnu.org/home/me/")
            ⇒ (path "http://gnu.org/home/me/")
     ‘(path-directory "./dir")’ ‘⇒’ ‘(path "./dir")’ if ‘dir’ is a
     directory, and ‘(path ".")’ otherwise.

 -- Procedure: path-parent arg
     Returns the “parent directory” of ARG (coerced to a ‘path’).  If
     ARG is not a directory, same as ‘path-directory ARG’.
          (path-parent "a/b/c") ⇒ (path "a/b")
          (path-parent "file:/a/b/c") ⇒ (path "file:/a/b/c")
          (path-parent "file:/a/b/c/") ⇒ (path "file:/a/b/")

 -- Procedure: path-last arg
     The last component of path component of ARG (coerced to a ‘path’).
     Returns a substring of ‘(path-file ARG)’.  If that string ends with
     ‘/’ or the path separator, that last character is ignored.  Returns
     the tail of the path-string, following the last (non-final) ‘/’ or
     path separator.
          (path-last "http:/a/b/c") ⇒ "c"
          (path-last "http:/a/b/c/") ⇒ "c"
          (path-last "a/b/c") ⇒ "c"

 -- Procedure: path-extension arg
     Returns the “extension” of the ARG (coerced to a ‘path’).
          (path-extension "http://gnu.org/home/me.html?add-bug#body") ⇒ "html"
          (path-extension "/home/.init") ⇒ #f

 -- Procedure: path-query arg
     Returns the query part of ARG (coerced to a ‘path’) if it is
     defined, or ‘#f’ otherwise.  The query part of a URI is the part
     after ‘?’.
          (path-query "http://gnu.org/home?add-bug") ⇒ "add-bug"

 -- Procedure: path-fragment arg
     Returns the fragment part of ARG (coerced to a ‘path’) if it is
     defined, or ‘#f’ otherwise.  The fragment of a URI is the part of
     after ‘#’.
          (path-query "http://gnu.org/home#top") ⇒ "top"

 -- Procedure: resolve-uri uri base
     Returns a URI unchanged if it is an absolute URI. Otherwise
     resolves it against a base URI BASE, which is normally (though not
     always) absolute.

     This uses the algorithm specifyed by RFC-3986 (assuming BASE is
     absolute), unlike the obsolete RFC-2396 algorithm used by
     ‘java.net.URI.resolve’.


File: kawa.info,  Node: Files,  Next: Reading and writing whole files,  Prev: Paths,  Up: Input-Output

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

 -- Procedure: file-exists? filename
     Returns true iff the file named FILENAME actually exists.  This
     function is defined on arbitrary ‘path’ values: for URI values we
     open a ‘URLConnection’ and invoke ‘getLastModified()’.

 -- Procedure: file-directory? filename
     Returns true iff the file named FILENAME actually exists and is a
     directory.  This function is defined on arbitrary ‘path’ values;
     the default implementation for non-file objects is to return ‘#t’
     iff the path string ends with the character ‘/’.

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

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

 -- Procedure: delete-file filename
     Delete the file named FILENAME.  On failure, throws an exception.

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

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

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

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

 -- Procedure: 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 implementation is safe from
     race conditions, and the returned filename will not be reused by
     this JVM.


File: kawa.info,  Node: Reading and writing whole files,  Next: Ports,  Prev: Files,  Up: Input-Output

17.4 Reading and writing whole files
====================================

The following procedures and syntax allow you to read and write the
entire contents of a file, without iterating using a port.

17.4.1 Reading a file
---------------------

For reading the contents of a file in a single operation, you can use
the following syntax:

     ‘&<{’NAMED-LITERAL-PART+‘}’

   This is equivalent to using the ‘path-data’ function (defined below):
     ‘(path-data’ ‘&{’NAMED-LITERAL-PART+‘})’

   For example:
     (define dir "/home/me/")
     (define help-message &<{&[dir]HELP})
   This binds ‘help-message’ to the contents of the file named ‘HELP’ in
the ‘dir’ directory.

17.4.2 Blobs
------------

The content of a file is, in general, a sequence of uninterpreted bytes.
Often these bytes represent text in a locale-dependent encoding, but we
don’t always know this.  Sometimes they’re images, or videos, or
word-processor documents.  A filename extension or a “magic number” in
the file can give you hints, but not certainty as to the type of the
data.

   A “blob (http://en.wikipedia.org/wiki/Binary_large_object)” is a raw
uninterpreted sequence of bytes.  It is a ‘bytevector’ that can be
automatically converted to other types as needed, specifically to a
string or a bytevector.

   The ‘&<{..}’ returns a blob.  For example, assume the file ‘README’
contains (bytes representing) the text ‘"Check doc directory.\n"’.
Then:
     #|kawa:1|# (define readme &<{README}))
     |kawa:2|# readme:class
     class gnu.lists.Blob
     #|kawa:3|# (write (->string readme))
     "Check doc directory.\n"
     #|kawa:4|# (write (->bytevector readme))
     #u8(67 104 101 99 107 32 100 111 99 32 100 105 114 101 99 116 111 114 121 46 10)
     #|kawa:5|# (->bytevector readme):class
     class gnu.lists.U8Vector

17.4.3 Writing to a file
------------------------

The ‘&<{..}’ syntax can be used with ‘set!’ to replace the contents of a
file:
     (set! &<{README} "Check example.com\n")

   The new contents must be blob-compatible - i.e.  a bytevector or a
string.

   If you dislike using ‘<’ as an output operator, you can instead using
the ‘&>{..}’ operation, which evaluates to a function whose single
argument is the new value:
     (&>{README} "Check example.com\n")
   In general:
     &>{NAMED-LITERAL-PART+}
   is equivalent to:
     (lambda (new-contents)
       (set! &<{NAMED-LITERAL-PART+} new-contents))

   You can use ‘&>>’ to append more data to a file:

     (&>>{README} "or check example2.com\n")

17.4.4 Functions
----------------

 -- Procedure: path-data path
     Reads the contents of the file specified by PATH, where PATH can be
     a *note path: Paths. object, or anything that can be converted to a
     ‘Path’, including a filename string or a URL. returning the result
     as a blob.  The result is a _blob_, which is a kind of bytevector
     than can be auto-converted to a string or bytevecor as required.

     The function ‘path-data’ has a setter, which replaces the contents
     with new contents:
          (set! &<{file-name} new-contents)

 -- Procedure: path-bytes path
     Reads the contents of the file specified by PATH, as with the
     ‘path-data’ function, but the result is a plain bytevector, rather
     than a blob.  This functtion also has a setter, which you can use
     to replace the file-contents by new bytevector-valued data.


File: kawa.info,  Node: Ports,  Next: Format,  Prev: Reading and writing whole files,  Up: Input-Output

17.5 Ports
==========

Ports represent input and output devices.  An input port is a Scheme
object that can deliver data upon command, while an output port is a
Scheme object that can accept data.

   Different “port types” operate on different data:
   • A “textual port” supports reading or writing of individual
     characters from or to a backing store containing characters using
     ‘read-char’ and ‘write-char’ below, and it supports operations
     defined in terms of characters, such as ‘read’ and ‘write’.
   • A “binary port” supports reading or writing of individual bytes
     from or to a backing store containing bytes using ‘read-u8’ and
     ‘write-u8’ below, as well as operations defined in terms of bytes
     (integers in the range 0 to 255).

     All Kawa binary ports created by procedures documented here are
     also textual ports.  Thus you can either read/write bytes as
     described above, or read/write characters whose scalar value is in
     the range 0 to 255 (i.e.  the Latin-1 character set), using
     ‘read-char’ and ‘write-char’.

     A native binary port is a ‘java.io.InputStream’ or
     ‘java.io.OutputStream’ instance.  These are not textual ports.  You
     can use methods ‘read-u8’ and ‘write-u8’, but not ‘read-char’ and
     ‘write-char’ on native binary ports.  (The functions ‘input-port?’,
     ‘output-port?’, ‘binary-port?’, and ‘port?’ all currently return
     false on native binary ports, but that may change.)

 -- Procedure: call-with-port port proc
     The ‘call-with-port’ procedure calls PROC with port as an argument.
     If PROC returns, then the port is closed automatically and the
     values yielded by the proc are returned.

     If PROC does not return, then the port must not be closed
     automatically unless it is possible to prove that the port will
     never again be used for a read or write operation.

     As a Kawa extension, PORT may be any object that implements
     ‘java.io.Closeable’.  It is an error if PROC does not accept one
     argument.

 -- Procedure: call-with-input-file path proc
 -- Procedure: call-with-output-file path proc
     These procedures obtain a textual port obtained by opening the
     named file for input or output as if by ‘open-input-file’ or
     ‘open-output-file’.  The port and PROC are then passed to a
     procedure equivalent to ‘call-with-port’.

     It is an error if PROC does not accept one argument.

 -- Procedure: input-port? obj
 -- Procedure: output-port? obj
 -- Procedure: textual-port? obj
 -- Procedure: binary-port? obj
 -- Procedure: port? obj
     These procedures return ‘#t’ if obj is an input port, output port,
     textual port, binary port, or any kind of port, respectively.
     Otherwise they return ‘#f’.

     These procedures currently return ‘#f’ on a native Java streams
     (‘java.io.InputStream’ or ‘java.io.OutputStream’), a native reader
     (a ‘java.io.Reader’ that is not an ‘gnu.mapping.Inport’), or a
     native writer (a ‘java.io.Writer’ that is not an
     ‘gnu.mapping.Outport’).  This may change if conversions between
     native ports and Scheme ports becomes more seamless.

 -- Procedure: input-port-open? port
 -- Procedure: output-port-open? port
     Returns ‘#t’ if PORT is still open and capable of performing input
     or output, respectively, and ‘#f’ otherwise.  (Not supported for
     native binary ports - i.e.  ‘java.io.InputStteam’ or
     ‘java.io.OutputStream’.)

 -- Procedure: current-input-port
 -- Procedure: current-output-port
 -- Procedure: current-error-port
     Returns the current default input port, output port, or error port
     (an output port), respectively.  (The error port is the port to
     which errors and warnings should be sent - the “standard error” in
     Unix and C terminology.)  These procedures are *note parameter
     objects: Parameter objects, which can be overridden with *note
     ‘parameterize’: parameterize-syntax.

     The initial bindings for ‘(current-output-port)’ and
     ‘(current-error-port)’ are hybrid textual/binary ports that wrap
     the values of the corresponding ‘java.lang.System’ fields ‘out’,
     and ‘err’.  The latter, in turn are bound to the standard output
     and error streams of the JVM process.  This means you can write
     binary data to standard output using ‘write-bytevector’ and
     ‘write-u8’.

     The initial value ‘(current-input-port)’ similarly is a textual
     port that wraps the ‘java.lang.System’ field ‘in’, which is bound
     to the standard input stream of the JVM process.  It is a _hybrid_
     textual/binary port only if there is no console (as determined by
     ‘(java.lang.System:console)’ returning ‘#!null’) - i.e.  if
     standard input is not a tty.

     Here is an example that copies standard input to standard output:
          (let* ((in (current-input-port))
                 (out (current-output-port))
                 (blen ::int 2048)
                 (buf (make-bytevector blen)))
            (let loop ()
              (define n (read-bytevector! buf in))
              (cond ((not (eof-object? n))
                     (write-bytevector buf out 0 n)
                     (loop)))))

 -- Procedure: with-input-from-file path thunk
 -- Procedure: with-output-to-file path thunk
     The file is opened for input or output as if by ‘open-input-file’
     or ‘open-output-file’, and the new port is made to be the value
     returned by ‘current-input-port’ or ‘current-output-port’ (as used
     by ‘(read)’, ‘(write OBJ)’, and so forth).  The thunk is then
     called with no arguments.  When the THUNK returns, the port is
     closed and the previous default is restored.  It is an error if
     THUNK does not accept zero arguments.  Both procedures return the
     values yielded by THUNK.  If an escape procedure is used to escape
     from the continuation of these procedures, they behave exactly as
     if the current input or output port had been bound dynamically with
     ‘parameterize’.

 -- Procedure: open-input-file path
 -- Procedure: open-binary-input-file path
     Takes a PATH naming an existing file and returns a textual input
     port or binary input port that is capable of delivering data from
     the file.

     The procedure ‘open-input-file’ checks the fluid variable *note
     ‘port-char-encoding’: port-char-encoding. to determine how bytes
     are decoded into characters.  The procedure
     ‘open-binary-input-file’ is equivalent to calling ‘open-input-file’
     with ‘port-char-encoding’ set to ‘#f’.

 -- Procedure: open-output-file path
 -- Procedure: open-binary-output-file path
     Takes a PATH naming an output file to be created and returns
     respectively a textual output port or binary output port that is
     capable of writing data to a new file by that name.  If a file with
     the given name already exists, the effect is unspecified.

     The procedure ‘open-output-file’ checks the fluid variable *note
     ‘port-char-encoding’: port-char-encoding. to determine how
     characters are encoded as bytes.  The procedure
     ‘open-binary-output-file’ is equivalent to calling
     ‘open-output-file’ with ‘port-char-encoding’ set to ‘#f’.

 -- Procedure: close-port port
 -- Procedure: close-input-port port
 -- Procedure: close-output-port port
     Closes the resource associated with PORT, rendering the port
     incapable of delivering or accepting data.  It is an error to apply
     the last two procedures to a port which is not an input or output
     port, respectively.  (Specifically, ‘close-input-port’ requires a
     ‘java.io.Reader’, while ‘close-output-port’ requires a
     ‘java.io.Writer’.  In contrast ‘close-port’ accepts any object
     whose class implements ‘java.io.Closeable’.)

     These routines have no effect if the port has already been closed.

17.5.1 String and bytevector ports
----------------------------------

 -- Procedure: open-input-string string
     Takes a string and returns a text 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

 -- Procedure: open-output-string
     Returns an textual 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)"

 -- Procedure: 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 in the order they were output.  If the result string is
     modified, the effect is unspecified.

          (parameterize
              ((current-output-port (open-output-string)))
              (display "piece")
              (display " by piece ")
              (display "by piece.")
              (newline)
              (get-output-string (current-output-port)))
                  ⇒ "piece by piece by piece.\n"

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

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

 -- Procedure: open-input-bytevector bytevector
     Takes a bytevector and returns a binary input port that delivers
     bytes from the bytevector.

 -- Procedure: open-output-bytevector
     Returns a binary output port that will accumulate bytes for
     retrieval by ‘get-output-bytevector’.

 -- Procedure: get-output-bytevector port
     Returns a bytevector consisting of the bytes that have been output
     to the port so far in the order they were output.  It is an error
     if PORT was not created with ‘open-output-bytevector’.

17.5.2 Input
------------

If PORT is omitted from any input procedure, it defaults to the value
returned by ‘(current-input-port)’.  It is an error to attempt an input
operation on a closed port.

 -- Procedure: read [port]
     The ‘read’ procedure converts external representations of Scheme
     objects into the objects themselves.  That is, it is a parser for
     the non-terminal DATUM.  It returns the next object parsable from
     the given textual input port, updating port to point to the first
     character past the end of the external representation of the
     object.

     If an end of file is encountered in the input before any characters
     are found that can begin an object, then an end-of-file object is
     returned.  The port remains open, and further attempts to read will
     also return an end-of-file object.  If an end of file is
     encountered after the beginning of an object’s external
     representation, but the external representation is incomplete and
     therefore not parsable, an error that satisfies ‘read-error?’ is
     signaled.

 -- Procedure: read-char [port]
     Returns the next character available from the textual input PORT,
     updating the port to point to the following character.  If no more
     characters are available, an end-of-file value is returned.

     The result type is ‘character-or-eof’.

 -- Procedure: peek-char [port]
     Returns the next character available from the textual input PORT,
     but _without_ updating the port to point to the following
     character.  If no more characters are available, an end-of-file
     value is returned.

     The result type is ‘character-or-eof’.

     _Note:_ The value returned by a call to ‘peek-char’ is the same as
     the value that would have been returned by a call to ‘read-char’
     with the same PORT.  The only difference is that the very next call
     to ‘read-char’ or ‘peek-char’ on that PORT will return the value
     returned by the preceding call to ‘peek-char’.  In particular, a
     call to ‘peek-char’ on an interactive port will hang waiting for
     input whenever a call to ‘read-char’ would have hung.

 -- Procedure: read-line [port [handle-newline]]
     Reads a line of input from the textual input 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.  If an end of file is encountered before any end
     of line is read, but some characters have been read, a string
     containing those characters is returned.  (In this case, ‘'trim’,
     ‘'peek’, and ‘'concat’ have the same result and effect.  The
     ‘'split’ case returns two values: The characters read, and the
     delimiter is an empty string.)  If an end of file is encountered
     before any characters are read, an end-of-file object is returned.
     For the purpose of this procedure, an end of line consists of
     either a linefeed character, a carriage return character, or a
     sequence of a carriage return character followed by a linefeed
     character.

 -- Procedure: eof-object? obj
     Returns ‘#t’ if OBJ is an end-of-file object, otherwise returns
     ‘#f’.

     ‘Performance note’: If OBJ has type ‘character-or-eof’, this is
     compiled as an ‘int’ comparison with -1.

 -- Procedure: eof-object
     Returns an end-of-file object.

 -- Procedure: char-ready? [port]
     Returns ‘#t’ if a character is ready on the textual input PORT and
     returns ‘#f’ otherwise.  If char-ready returns ‘#t’ then the next
     ‘read-char’ operation on the given PORT is guaranteed not to hang.
     If the port is at end of file then ‘char-ready?’ returns ‘#t’.

     _Rationale:_ The ‘char-ready?’ procedure exists to make it possible
     for a program to accept characters from interactive ports without
     getting stuck waiting for input.  Any input editors as- sociated
     with such ports must ensure that characters whose existence has
     been asserted by ‘char-ready?’ cannot be removed from the input.
     If ‘char-ready?’ were to return ‘#f’ at end of file, a port at
     end-of-file would be indistinguishable from an interactive port
     that has no ready characters.

 -- Procedure: read-string k [port]
     Reads the next K characters, or as many as are available before the
     end of file, from the textual input PORT into a newly allocated
     string in left-to-right order and returns the string.  If no
     characters are available before the end of file, an end-of-file
     object is returned.

 -- Procedure: read-u8 [port]
     Returns the next byte available from the binary input PORT,
     updating the PORT to point to the following byte.  If no more bytes
     are available, an end-of-file object is returned.

 -- Procedure: peek-u8 [port]
     Returns the next byte available from the binary input PORT, but
     _without_ updating the PORT to point to the following byte.  If no
     more bytes are available, an end-of-file object is returned.

 -- Procedure: u8-ready? [port]
     Returns ‘#t’ if a byte is ready on the binary input PORT and
     returns ‘#f’ otherwise.  If ‘u8-ready?’ returns ‘#t’ then the next
     ‘read-u8’ operation on the given port is guaranteed not to hang.
     If the port is at end of file then ‘u8-ready?’ returns ‘#t’.

 -- Procedure: read-bytevector k [port]
     Reads the next K bytes, or as many as are available before the end
     of file, from the binary input PORT into a newly allocated
     bytevector in left-to-right order and returns the bytevector.  If
     no bytes are available before the end of file, an end-of-file
     object is returned.

 -- Procedure: read-bytevector! bytevector [port [start [end]]]
     Reads the next END − START bytes, or as many as are available
     before the end of file, from the binary input PORT into BYTEVECTOR
     in left-to-right order beginning at the START position.  If END is
     not supplied, reads until the end of BYTEVECTOR has been reached.
     If START is not supplied, reads beginning at position 0.  Returns
     the number of bytes read.  If no bytes are available, an
     end-of-file object is returned.

17.5.3 Output
-------------

If PORT is omitted from any output procedure, it defaults to the value
returned by ‘(current-output-port)’.  It is an error to attempt an
output operation on a closed port.

   The return type of these methods is ‘void’.

 -- Procedure: write obj [port]
     Writes a representation of OBJ to the given textual output PORT.
     Strings that appear in the written representation are enclosed in
     quotation marks, and within those strings backslash and quotation
     mark characters are escaped by backslashes.  Symbols that contain
     non-ASCII characters are escaped with vertical lines.  Character
     objects are written using the ‘#\’ notation.

     If OBJ contains cycles which would cause an infinite loop using the
     normal written representation, then at least the objects that form
     part of the cycle must be represented using *note datum labels::.
     Datum labels must not be used if there are no cycles.

 -- Procedure: write-shared obj [port]
     The ‘write-shared’ procedure is the same as ‘write’, except that
     shared structure must be represented using datum labels for all
     pairs and vectors that appear more than once in the output.

 -- Procedure: write-simple obj [port]
     The ‘write-simple’ procedure is the same as ‘write’, except that
     shared structure is never represented using datum labels.  This can
     cause write-simple not to terminate if OBJ contains circular
     structure.

 -- Procedure: display obj [port]
     Writes a representation of OBJ to the given textual output port.
     Strings that appear in the written representation are output as if
     by ‘write-string’ instead of by ‘write’.  Symbols are not escaped.
     Character objects appear in the representation as if written by
     ‘write-char’ instead of by ‘write’.  The ‘display’ representation
     of other objects is unspecified.

 -- Procedure: newline [port]
     Writes an end of line to textual output PORT.  This is done using
     the ‘println’ method of the Java class ‘java.io.PrintWriter’.

 -- Procedure: write-char char [port]
     Writes the character CHAR (not an external representation of the
     character) to the given textual output PORT.

 -- Procedure: write-string string [port [start [end]]]
     Writes the characters of STRING from START to END in left-to-right
     order to the textual output PORT.

 -- Procedure: write-u8 byte [port]
     Writes the BYTE to the given binary output port.

 -- Procedure: write-bytevector bytevector [port [start [end]]]
     Writes the bytes of BYTEVECTOR from START to END in left-to-right
     order to the binary output PORT.

 -- Procedure: flush-output-port [port]
 -- Procedure: force-output [port]
     Forces any pending output on PORT to be delivered to the output
     file or device and returns an unspecified value.  If the PORT
     argument is omitted it defaults to the value returned by
     ‘(current-output-port)’.  (The name ‘force-output’ is older, while
     R6RS added ‘flush-output-port’.  They have the same effect.)

17.5.4 Prompts for interactive consoles (REPLs)
-----------------------------------------------

When an interactive input port is used for a read-eval-print-loop (REPL
or console) it is traditional for the REPL to print a short “prompt”
string to signal that the user is expected to type an expression.  These
prompt strings can be customized.

 -- Variable: input-prompt1
 -- Variable: input-prompt2
     These are fluid variable whose values are string templates with
     placeholders similar to ‘printf’-style format.  The placeholders
     are expanded (depending on the current state), and the resulting
     string printed in front of the input line.

     The ‘input-prompt1’ is used normally.  For multi-line input
     commands (for example if the first line is incomplete),
     ‘input-prompt1’ is used for the first line of each command, while
     ‘input-prompt2’ is used for subsequent “continuation” lines.

     The following placeholders are handled:
     ‘%%’
          A literal ‘%’.
     ‘%N’
          The current line number.  This is ‘(+ 1 (port-line PORT))’.
     ‘%’N‘P’C
          Insert padding at this possion, repeating the following
          character ‘C’ as needed to bring the total number of columns
          of the prompt to that specified by the digits ‘N’.
     ‘%P’C
          Same as ‘%NPC’, but ‘N’ defaults to the number of columns in
          the initial prompt from the expansion of ‘input-prompt1’.
          This is only meaningful when expanding ‘input-prompt2’ for
          continuation lines.
     ‘%’‘{’HIDDEN‘%}’
          Same as HIDDEN, but the characters of HIDDEN are assumed to
          have zero visible width.  Can be used for ANSI escape
          sequences (https://en.wikipedia.org/wiki/ANSI_escape_code) to
          change color or style:
               (set! input-prompt1 "%{\e[48;5;51m%}{Kawa:%N} %{\e[0m%}")
          The above changes both the text and the background color (to a
          pale blue).
     ‘%H’CD
          If running under DomTerm, use the characters C and D as a
          clickable mini-button to hide/show (fold) the command and its
          output.  (When output is visible C is displayed; clicking on
          it hides the output.  When output is hidden D is displayed;
          clicking on it shows the output.)  Ignored if not running
          under DomTerm.
     ‘%M’
          Insert a “message” string.  Not normally used by Kawa, but
          supported by JLine.

     These variables can be initialized by the command-line arguments
     ‘console:prompt1=PROMPT1’ and ‘console:prompt2=PROMPT2’,
     respectively.  If these are not specified, languages-specific
     defaults are used.  For example for Scheme the default value of
     ‘input-prompt1’ is ‘"#|%H▼▶kawa:%N|# "’ and ‘input-prompt2’ is
     ‘"#|%P.%N| "’.  These have the form of Scheme comments, to make it
     easier to cut-and-paste.

     If ‘input-prompt1’ (respectively ‘input-prompt2’) does not contain
     an escape sequence (either ‘"%{’ or the escape character ‘"\e"’)
     then ANSI escape sequences are added to to highlight the prompt.
     (Under DomTerm this sets the ‘prompt’ style, which can be
     customised with CSS but defaults to a light green background; if
     using JLine the background is set to light green.)

   For greater flexibility, you can also set a prompter procedure.

 -- Procedure: 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.  The procedure is called before reading the
     first line of a command; its return value is used as the first-line
     prompt.

     The prompt procedure can have side effects.  In Bash shell terms:
     It combines the features of ‘PROMPT_COMMAND’ and ‘PS1’.

     The initial PROMPTER is ‘default-prompter’, which returns the
     expansion of ‘input-prompt1’.

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

 -- Procedure: default-prompter port
     The default prompt procedure.  Normally (i.e.  when
     ‘input-port-read-state’ is a space) returns ‘input-prompt1’ after
     expanding the ‘%’-placeholders.  Can also expand ‘input-prompt2’
     when ‘input-port-read-state’ is not whitespace.

17.5.5 Line numbers and other input port properties
---------------------------------------------------

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

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

 -- Procedure: 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))’.

 -- Procedure: 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))’.

 -- Procedure: 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))’.

 -- Procedure: 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.)  The value of ‘symbol-read-case’ only checked when a
     reader is created, not each time a symbol is read.

17.5.6 Miscellaneous
--------------------

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

 -- Variable: *print-base*
     The number base (radix) to use by default when printing rational
     numbers.  Must be an integer between 2 and 36, and the default is
     of course 10.  For example setting ‘*print-base*’ to 16 produces
     hexadecimal output.

 -- Variable: *print-radix*
     If true, prints an indicator of the radix used when printing
     rational numbers.  If ‘*print-base*’ is respectively 2, 8, or 16,
     then ‘#b’, ‘#o’ or ‘#x’ is written before the number; otherwise
     ‘#Nr’ is written, where ‘N’ is the base.  An exception is when
     ‘*print-base*’ is 10, in which case a period is written _after_ the
     number, to match Common Lisp; this may be inappropriate for Scheme,
     so is likely to change.

 -- Variable: *print-right-margin*
     The right margin (or line width) to use when pretty-printing.

 -- Variable: *print-miser-width*
     If this an integer, and the available width is less or equal to
     this value, then the pretty printer switch to the more “miser”
     compact style.

 -- Variable: *print-xml-indent*
     When writing to XML, controls pretty-printing and indentation.  If
     the value is ‘'always’ or ‘'yes’ force each element to start on a
     new suitably-indented line.  If the value is ‘'pretty’ only force
     new lines for elements that won’t fit completely on a line.  The
     the value is ‘'no’ or unset, don’t add extra whitespace.


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

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

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

 -- Procedure: 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’!

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

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

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

17.6.4 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
‘~<’MINCOL
     Start justification: spacing is evenly distributed between text
     segments with a width of MINCOL.  This enables an even right
     margin.
‘~>’
     End of segments to justify.

17.6.5 Unimplemented CL Format Control Directives
-------------------------------------------------

‘~:A’
     print ‘#f’ as an empty list (see below).
‘~:S’
     print ‘#f’ as an empty list (see below).
‘~:^’

17.6.6 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: Pretty-printing,  Next: Resources,  Prev: Format,  Up: Input-Output

17.7 Pretty-printing
====================

Pretty-printing is displaying a data structure as text, by adding
line-breaks and indenttaion so that the visual structure of the output
corresponds to the logical structure of data structure.  This makes it
easier to read and understand.  Pretty-printing takes into account the
column width of the output so as to avoid using more lines than needed.

   Pretty-printing of standard sequences types such as lists and vectors
is done by default.  For example:
     #|kawa:11|# (set! *print-right-margin* 50)
     #|kawa:12|# '(ABCDEF (aa bb cc dd) (x123456789
     #|.....13|# y123456789 z123456789) ABCDEFG HIJKL)
     (ABCDEF (aa bb cc dd)
      (x123456789 y123456789 z123456789) ABCDEFG HIJK)
   Setting ‘*print-right-margin*’ to 50 causes output to be limited to
50 columns.  Notice the top-level list has to be split, but sub-lists
‘(aa bb cc dd)’ and ‘(x123456789 y123456789 z123456789)’ don’t need to
be split.

   When outputting to a DomTerm REPL, then ‘*print-right-margin*’ is
ignored, and the line-breaking is actually handled by DomTerm.  If you
change the window width, DomTerm will dynamically re-calculate the
line-breaks of previous pretten output.  This works even in the case of
a session saved to an HTML file, as long as JavaScript is enabled.

   The concepts and terminology are based on those of Common Lisp
(https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node253.html).

17.7.1 Pretty-printing Scheme forms
-----------------------------------

Scheme and Lisp code is traditionally pretty-printed slightly
differently than plain lists.  The ‘pprint’ procedure assumes the
argument is a Scheme form, and prints its accordingly.  For example the
special form ‘(let ...)’ is printed differently from a regular function
call ‘(list ...)’.

 -- Procedure: pprint obj [out]
     Assume OBJ is a Scheme form, and pretty-print it in traditional
     Scheme format.  For example:
          #|kawa:1|# (import (kawa pprint))
          #|kawa:2|# (define fib-form
          #|.....3|#   '(define (fibonacci n)
          #|.....4|#      (let loop ((i0 0) (i1 1) (n n))
          #|.....5|#        (if (<= n 0) i0
          #|.....6|#            (loop i1 (+ i0 i1) (- n 1))))))
          #|kawa:7|# (set! *print-right-margin* 80)
          #|kawa:8|# (pprint fib-form)
          (define (fibonacci n)
            (let loop ((i0 0) (i1 1) (n n)) (if (<= n 0) i0 (loop i1 (+ i0 i1) (- n 1)))))
          #|kawa:9|# (set! *print-right-margin* 40)
          #|kawa:10|# (pprint fib-form)
          (define (fibonacci n)
            (let loop ((i0 0) (i1 1) (n n))
              (if (<= n 0)
                  i0
                  (loop i1 (+ i0 i1) (- n 1)))))

     The ‘pprint’ special-cases forms that start with ‘define’, ‘if’,
     ‘lambda’, ‘let’, and a few more, and formats them with
     “traditional” indentation.  However, it is not as complete or
     polished as it should be.  (It should also use a programmable
     dispatch table, rather than having these special cases hard-wired.
     That is an improvemet for another day.)

17.7.2 Generic pretty-printing functions
----------------------------------------

The following procedures are used to indicate logical blocks, and
optional newlines.

   To access them do:
     (import (kawa pprint))

   In the following, OUT is the output port, which defaults to
‘(current-output-port)’.

 -- Syntax: pprint-logical-block OPTIONS STATEMENT^{*}

     Evaluate the STATEMENTs within the context of a new “logical
     block”.

     The OPTIONS are one or more of the following:
     ‘prefix:’ PREFIX
     ‘per-line:’ PER-LINE-PREFIX
          Emit PREFIX or PER-LINE-PREFIX (only one of them can be
          specified) before the start of the logical block.  If
          PER-LINE-PREFIX is provided, it is also print for each line
          within the logical block, indented the same.  These are
          strings and default to ‘""’.
     ‘suffix:’ SUFFIX
          Emit SUFFIX after the end of the logical block.
     ‘out:’ OUT
          The output file.

     For example to print a list you might do:
          (pprint-logical-block prefix: "(" suffix: ")"
             print contents of list)

     This macro is equivalent to:
          (pprint-start-logical-block PREFIX IS-PER-LINE SUFFIX OUT)
          (try-finally
            (begin STATEMENT^{*})
            (pprint-end-logical-block SUFFIX OUT))

 -- Procedure: pprint-start-logical-block prefix is-per-line suffix out
     Start a logical block.  The IS-PER-LINE argument is a boolean to
     specifiy of PREFIX is a per-line-prefix or a plain prefix.
 -- Procedure: pprint-end-logical-block suffix out
     End a logical block.

 -- Procedure: pprint-newline kind [out]
     Print a conditional newline, where KIND is one of the symbols
     ‘'fill’, ‘'linear’, ‘'mandatory’, or ‘'miser’.  Usually follows
     printing of a space, as nothing is printed if the line is not
     broken here.

 -- Procedure: pprint-ident mode amount [out]
     Change how much following lines are indented (with the current
     logical block).  The AMOUNT is the size of the indentation, in
     characters.  The MODE is either ‘'current’ (if the AMOUNT is
     relative to the current position), or ‘'block’ (if the AMOUNT is
     relative to the start (after any PREFIX) of the current logical
     block).


File: kawa.info,  Node: Resources,  Prev: Pretty-printing,  Up: Input-Output

17.8 Resources
==============

A resource is a file or other fixed data that an application may access.
Resources are part of the application and are shipped with it, but are
stored in external files.  Examples are images, sounds, and translation
(localization) of messages.  In the Java world a resource is commonly
bundled in the same jar file as the application itself.

 -- Syntax: resource-url resource-name
     Returns a ‘URLPath’ you can use as a ‘URL’, or you can pass to it
     ‘open-input-file’ to read the resource data.  The RESOURCE-NAME is
     a string which is passed to the ‘ClassLoader’ of the containing
     module.  If the module class is in a jar file, things will
     magically work if the resource is in the same jar file, and
     RESOURCE-NAME is a filename relative to the module class in the
     jar.  If the module is immediately evaluated, the RESOURCE-NAME is
     resolved against the location of the module source file.

 -- Syntax: module-uri
     Evaluates to a special URI that can be used to access resources
     relative to the class of the containing module.  The URI has the
     form ‘"class-resource://CURRENTCLASS/"’ in compiled code, to allow
     moving the classes/jars.  The current ‘ClassLoader’ is associated
     with the URI, so accessing resources using the URI will use that
     ‘ClassLoader’.  Therefore you should not create a
     ‘"class-resource:"’ URI except by using this function or
     ‘resolve-uri’, since that might try to use the wrong ‘ClassLoader’.

     The macro ‘resource-url’ works by using ‘module-uri’ and resolving
     that to a normal ‘URL’.

 -- Syntax: module-class
     Evaluates to the containing module class, as a ‘java.lang.Class’
     instance.


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

18 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.  The most used types correspond
to Java classes and primitive types, but Kawa also has other non-Java
types.

   Type specifiers have a “type expressions”, and a type expression is
conceptually an expression that 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.

     TYPE ::= EXPRESSION
     OPT-TYPE-SPECIFIER ::= [‘::’ TYPE]

   Various Kawa constructs require or allow a type to be specified.  You
can use a type specifier most places where you *note define a variable
or match a pattern: Variables and Patterns.  Types specifiers can appear
in other placess, such as procedure return type specifiers.  For example
in this procedure definition, ‘::vector’ is an argument type specifier
(and ‘vec::vector’ is a pattern), while ‘::boolean’ is a return type
specifier.
     (define (vector-even? vec::vector)::boolean
       (not (odd? (vector-length vec))))
     (vector-even? #(3 4 5)) ⇒ #f
     (vector-even? (list 3 4 5 6)) ⇒ error

* Menu:

* Standard Types::
* Parameterized Types::
* Type tests and conversions::


File: kawa.info,  Node: Standard Types,  Next: Parameterized Types,  Up: Types

18.1 Standard Types
===================

These types are predefined with the following names.

   Instead of plain ‘TYPENAME’ you can also use the syntax ‘<TYPENAME>’
with angle brackets, but that syntax is no longer recommended, because
it doesn’t “fit” as well with some ways type names are used.

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

   The numeric types (‘number’, ‘quantity’, ‘complex’, ‘real’,
‘rational’, ‘integer’, ‘long’, ‘int’, ‘short’, ‘byte’ ‘ulong’, ‘uint’,
‘ushort’, ‘ubyte’, ‘double’, ‘float’) are discussed in *note Numerical
types::.

   The types ‘character’ and ‘char’ are discussed in *note Characters::.

 -- Variable: Object
     An arbitrary Scheme value - and hence an arbitrary Java object.

 -- Variable: symbol
     The type of Scheme symbols.  (Implemented using the Java class
     ‘gnu.mapping.Symbol’.)  (_Compatibility:_ Previous versions of Kawa
     implemented a simple Scheme symbol using an interned
     ‘java.lang.String’.)

 -- 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 Scheme strings.  (Implemented using ‘gnu.lists.IString’
     or ‘java.lang.String’ for immutable strings, and
     ‘gnu.lists.FString’ for mutable strings.  These all implement the
     interface ‘java.lang.CharSequence’.  (_Compatibility:_ Previous
     versions of Kawa always used ‘gnu.lists.FString’.)

 -- 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’.  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 method, any parameter whose type is
     ‘java.lang.String’ is converted as if it was declared as a
     ‘String’.

 -- Variable: parameter
     A parameter object, as created by ‘make-parameter’.  This type can
     take a type parameter (sic):
          (define-constant client ::parameter[Client] (make-parameter #!null))
     This lets Kawa know that reading the parameter (as in ‘(client)’)
     returns a value of the specified type (in this case ‘Client’).

   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 value ‘#f’ is identical to
‘Boolean.FALSE’, and ‘#t’ is identical to ‘Boolean.TRUE’.)  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.

 -- Variable: dynamic
     Used to specify that the type is unknown, and is likely to change
     at run-time.  Warnings about unknown member names are supressed (a
     run-time name lookup is formed).  An expression of type ‘dynamic’
     is (statically) compatible with any type.


File: kawa.info,  Node: Parameterized Types,  Next: Type tests and conversions,  Prev: Standard Types,  Up: Types

18.2 Parameterized Types
========================

Kawa has some basic support for parameterized (generic) types.  The
syntax:
     Type[Arg1 Arg2 ... ArgN]
   is more-or-less equivalent to Java’s:
     Type<Arg1, Arg2, ..., ArgN>

   This is a work-in-progress.  You can use this syntax with
fully-qualified class names, and also type aliases:
     (define v1 ::gnu.lists.FVector[gnu.math.IntNum] [4 5 6])
     (define-alias fv gnu.lists.FVector)
     (define v2 ::fv[integer] [5 6 7])
     (define-alias fvi fv[integer])
     (define v3 ::fvi [6 7 8])


File: kawa.info,  Node: Type tests and conversions,  Prev: Parameterized Types,  Up: Types

18.3 Type tests and conversions
===============================

Scheme defines a number of standard type testing predicates.  For
example ‘(vector? x)’ is ‘#t’ if and only if ‘x’ is a vector.

   Kawa generalizes this to arbitrary type names: If T is a type-name
(that is in scope at compile-time), then ‘T?’ is a one-argument function
that returns ‘#t’ if the argument is an instance of the type ‘T’, and
‘#f’ otherwise:
     (gnu.lists.FVector? #(123)) ⇒ #t
     (let ((iarr (int[] 10))) (int[]? iarr)) ⇒ #t

   To convert (coerce) the result of an expression VALUE to a type T use
the syntax: ‘(->T VALUE)’.
     (->float 12) ⇒ 12.0f0

   In general:
     (T? X) ⇒ (instance? X T)
     (->T X) ⇒ (as T X)

 -- Procedure: instance? value type
     Returns ‘#t’ iff VALUE is an instance of type TYPE.  (Undefined if
     TYPE is a primitive type, such as ‘int’.)

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


File: kawa.info,  Node: Objects Classes and Modules,  Next: XML tools,  Prev: Types,  Up: Top

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

* Defining new classes::
* Anonymous classes::
* Enumerations::          Enumeration types
* Annotations::
* Module classes::        Modules and how they are compiled to classes
* Importing::             Importing from a library
* Record types::          Defining Record Types
* Dynamic records::       Creating New Record Types On-the-fly
* Method operations::     Calling Java methods from Scheme
* Allocating objects::
* Field operations::      Accessing fields of Java objects
* Mangling::              Mapping Scheme names to Java names
* Scheme types in Java::
* Array operations::      Using Java arrays
* Loading Java functions into Scheme::
* Evaluating Scheme expressions from Java::

 -- 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: Defining new classes,  Next: Anonymous classes,  Up: Objects Classes and Modules

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

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

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

 -- Syntax: define-class CLASS-NAME ‘(’supers ...‘)’
          (ANNOTATION|OPTION-PAIR)^{*} FIELD-OR-METHOD-DECL ...
 -- Syntax: define-simple-class CLASS-NAME ‘(’supers ...‘)’
          (ANNOTATION|OPTION-PAIR)^{*} FIELD-OR-METHOD-DECL ...

     Defines a new class named CLASS-NAME.  If ‘define-simple-class’ is
     used, creates a normal Java class named CLASS-NAME in the current
     package.  (If CLASS-NAME has the form ‘<xyz>’ the Java
     implementation type is named ‘xyz’.)  For ‘define-class’ the
     implementation is unspecified.  In most cases, the compiler creates
     a class pair, consisting of a Java interface and a Java
     implementation class.
     CLASS-NAME ::= IDENTIFIER
     OPTION-PAIR ::= OPTION-KEYWORD OPTION-VALUE
     FIELD-OR-METHOD-DECL ::= FIELD-DECL | METHOD-DECL

19.1.1 General class properties
-------------------------------

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

‘interface:’ MAKE-INTERFACE
     Specifies whether Kawa generates a Java class, interface, or both.
     If MAKE-INTERFACE is ‘#t’, then a Java interface is generated.  In
     that case all the supertypes must be interfaces, and all the
     declared methods must be abstract.  If MAKE-INTERFACE is ‘#f’, then
     a Java class is generated.  If ‘interface:’ is unspecified, the
     default is ‘#f’ for ‘define-simple-class’.  For ‘define-class’ the
     default is to generate an interface, and in addition (if needed) a
     helper class that implements the interface.  (In that case any
     non-abstract methods are compiled to static methods.  The methods
     that implement the interface are just wrapper methods that call the
     real static methods.  This allows Kawa to implement true multiple
     inheritance.)

‘access:’ KIND
     Specifies the Java access permission on the class.  Can be one of
     ‘'public’ (which is the default in Kawa), ‘'package’ (which the
     default "unnamed" permission in Java code), ‘'protected’,
     ‘'private’, ‘'volatile’, or ‘'transient’.  Can also be used to
     specify ‘final’, ‘abstract’, or ‘enum’, as in Java.  (You don’t
     need to explicitly specify the class is ‘abstract’ if any
     METHOD-BODY is ‘#!abstract’, or you specify ‘interface: #t’.)  The
     KIND can also be a list, as for example:
          access: '(protected volatile)

‘class-name:’ ‘"’CNAME‘"’
     Specifies the Java name of the created class.  The NAME specified
     after ‘define-class’ or ‘define-simple-class’ is the _Scheme name_,
     i.e.  the name of a Scheme variable that is bound to the class.
     The Java name is by default derived from the Scheme name, but you
     can override the default with a ‘class-name:’ specifier.  If the
     CNAME has no periods, then it is a name in the package of the main
     (module) class.  If the CNAME starts with a period, then you get a
     class nested within the module class.  In this case the actual
     class name is MODULECLASS‘$’RNAME, where RNAME is CNAME without the
     initial period.  To force a class in the top-level (unnamed)
     package (something not recommended) write a period at the end of
     the CNAME.

19.1.2 Declaring fields
-----------------------

     FIELD-DECL ::= ‘(’FIELD-NAME (ANNOTATION | OPT-TYPE-SPECIFIER | FIELD-OPTION)*‘)’
     FIELD-NAME ::= IDENTIFIER
     FIELD-OPTION ::= KEYWORD EXPRESSION

   As a matter of style the following order is suggested, though this
not enforced:
     ‘(’FIELD-NAME ANNOTATION* OPT-TYPE-SPECIFIER FIELD-OPTION*‘)’

   Each FIELD-DECL declares a instance "slot" (field) with the given
FIELD-NAME.  By default it is publicly visible, but you can specify a
different visiblity with the ‘access:’ specifier.  The following
FIELD-OPTION KEYWORDs are implemented:
‘type:’ TYPE
     Specifies that TYPE is the type of (the values of) the field.
     Equivalent to ‘:: TYPE’.
‘allocation:’ KIND
     If KIND is ‘'class’ or ‘'static’ a single slot is shared between
     all instances of the class (and its sub-classes).  Not yet
     implemented for ‘define-class’, only for ‘define-simple-class’.  In
     Java terms this is a ‘static’ field.

     If KIND is ‘'instance’ then each instance has a separate value
     "slot", and they are not shared.  In Java terms, this is a
     non-‘static’ field.  This is the default.

‘access:’ KIND
     Specifies the Java access permission on the field.  Can be one of
     ‘'private’, ‘'protected’, ‘'public’ (which is the default in Kawa),
     or ‘'package’ (which the default "unnamed" permission in Java
     code).  Can also be used to specify ‘volatile’, ‘transient’,
     ‘enum’, or ‘final’, as in Java, or a quoted list with these
     symbols.
‘init:’ EXPR
     An expression used to initialize the slot.  The expression is
     evaluated in a scope that includes the field and method names of
     the current class.
‘init-form:’ EXPR
     An expression used to initialize the slot.  The lexical environment
     of the EXPR is that of the ‘define-class’; it does _not_ include
     the field and method names of the current class.  or
     ‘define-simple-class’.
‘init-value:’ VALUE
     A value expression used to initialize the slot.  For now this is
     synonymous with INIT-FORM:, but that may change (depending on what
     other implementation do), so to be safe only use ‘init-value:’ with
     a literal.
‘init-keyword:’ ‘NAME:’
     A keyword that that can be used to initialize instance in ‘make’
     calls.  For now, this is ignored, and NAME should be the same as
     the field’s FIELD-NAME.

   The FIELD-NAME can be left out.  That indicates a "dummy slot", which
is useful for initialization not tied to a specific field.  In Java
terms this is an instance or static initializer, i.e., a block of code
executed when a new instance is created or the class is loaded.

   In this example, ‘x’ is the only actual field.  It is first
initialized to 10, but if ‘(some-condition)’ is true then its value is
doubled.
     (define-simple-class <my-class> ()
       (allocation: 'class
        init: (perform-actions-when-the-class-is-initizalized))
       (x init: 10)
       (init: (if (some-condition) (set! x (* x 2)))))

19.1.3 Declaring methods
------------------------

     METHOD-DECL ::= ‘((’METHOD-NAME FORMAL-ARGUMENTS‘)’
         METHOD-OPTION^{*} [DEPRECATED-RETURN-SPECIFIER] METHOD-BODY‘)’
     METHOD-NAME ::= IDENTIFIER
     METHOD-OPTION ::= ANNOTATION | OPT-RETURN-TYPE | OPTION-PAIR
     METHOD-BODY ::= BODY | ‘#!abstract’ | ‘#!native’
     DEPRECATED-RETURN-SPECIFIER ::= IDENTIFIER

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

   A METHOD-DECL in a ‘define-simple-class’ can have the following
OPTION-KEYWORDs:
‘access:’ KIND
     Specifies the Java access permission on the method.  Can be one of
     ‘'private’, ‘'protected’, ‘'public’, or ‘'package’.  Can also be
     ‘'synchronized’, ‘'final’, ‘'strictfp’, or a quoted list.
‘allocation:’ KIND
     If KIND is ‘'class’ or ‘'static’ creates a static method.
‘throws:’ ( EXCEPTION-CLASS-NAME ... )
     Specifies a list of checked exception that the method may throw.
     Equivalent to a ‘throws’ specification in Java code.  For example:
          (define-simple-class T
            (prefix)
            ((lookup name) throws: (java.io.FileNotFoundException)
             (make java.io.FileReader (string-append prefix name))))

   The scope of the BODY of a method includes the FIELD-DECLs and
METHOD-DECLs of the class, including those inherited from superclasses
and implemented interfaces.

   If the METHOD-BODY is the special form ‘#!abstract’, then the method
is abstract.  This means the method must be overridden in a subclass,
and you’re not allowed to create an instance of the enclosing class.

     (define-simple-class Searchable () interface: #t
       ((search value) :: boolean #!abstract))

   If the METHOD-BODY is the special form ‘#!native’, then the method is
native, implemented using JNI
(http://en.wikipedia.org/wiki/Java_Native_Interface).

   The special METHOD-NAME ‘*init*’ can be used to name a non-default
constructor (only if MAKE-INTERFACE discussed above is ‘#f’).  It can be
used to initialize a freshly-allocated instance using passed-in
parameters.  You can call a superclass or a sibling constructor using
the ‘invoke-special’ special function.  (This is general but admittedly
a bit verbose; a more compact form may be added in the future.)  See the
example below.

19.1.4 Example
--------------

In the following example we define a simple class ‘2d-vector’ and a
class ‘3d-vector’ that extends it.  (This is for illustration only -
defining 3-dimensional points as an extension of 2-dimensional points
does not really make sense.)

     (define-simple-class 2d-vector ()
       (x ::double init-keyword: x:)
       ;; Alternative type-specification syntax.
       (y type: double init-keyword: y:)
       (zero-2d :: 2d-vector allocation: 'static
        init-value: (2d-vector 0))
       ;; An object initializer (constructor) method.
       ((*init* (x0 ::double) (y0 ::double))
        (set! x x0)
        (set! y y0))
       ((*init* (xy0 ::double))
        ;; Call above 2-argument constructor.
        (invoke-special 2d-vector (this) '*init* xy0 xy0))
       ;; Need a default constructor as well.
       ((*init*) #!void)
       ((add (other ::2d-vector)) ::2d-vector
        ;; Kawa compiles this using primitive Java types!
        (2d-vector
          x: (+ x other:x)
          y: (+ y other:y)))
       ((scale (factor ::double)) ::2d-vector
        (2d-vector x: (* factor x) y: (* factor y))))

     (define-simple-class 3d-vector (2d-vector)
       (z type: double init-value: 0.0 init-keyword: z:)
       ;; A constructor which calls the superclass constructor.
       ((*init* (x0 ::double) (y0 ::double) (z0 ::double))
        (invoke-special 2d-vector (this) '*init* x0 y0)
        (set! z z0))
       ;; Need a default constructor.
       ((*init*) #!void)
       ((scale (factor ::double)) ::2d-vector
        ;; Note we cannot override the return type to 3d-vector
        ;; because Kawa doesn't yet support covariant return types.
        (3d-vector
          x: (* factor x)
          y: (* factor (this):y) ;; Alternative syntax.
          z: (* factor z))))

   Note we define both explicit non-default constructor methods, and we
associate fields with keywords, so they can be named when allocating an
object.  Using keywords requires a default constructor, and since having
non-default constructors suppresses the implicit default constructor we
have to explicitly define it.  Using both styles of constructors is
rather redundant, though.


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

19.2 Anonymous classes
======================

 -- Syntax: object ‘(’supers ...‘)’ field-or-method-decl ...
     Returns a new instance of an anonymous (inner) class.  The syntax
     is similar to ‘define-class’.
          OBJECT-FIELD-OR-METHOD-DECL ::= OBJECT-FIELD-DECL | METHOD-DECL
          OBJECT-FIELD-DECL ::= ‘(’FIELD-NAME (ANNOTATION | OPT-TYPE-SPECIFIER | FIELD-OPTION)*  [OBJECT-INIT] ‘)’
          OBJECT-INIT ::= EXPRESSION

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

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

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

     A METHOD-DECL is as for ‘define-class’.

19.2.1 Lambda as shorthand for anonymous class
----------------------------------------------

An anonymous class is commonly used in the Java platform where a
function language would use a lambda expression.  Examples are call-back
handlers, events handlers, and ‘run’ methods.  In these cases Kawa lets
you use a lambda expression as a short-hand for an anonymous class.  For
example:
     (button:addActionListener
       (lambda (e) (do-something)))
   is equivalent to:
     (button:addActionListener
       (object (java.awt.event.ActionListener)
         ((actionPerformed (e ::java.awt.event.ActionEvent))::void
          (do-something))))
   This is possible when the required type is an interface or abstract
class with a Single (exactly one) Abstract Methods.  Such a class is
sometimes called a “SAM-type”, and the conversion from a lambda
expression to an anonymous class is sometimes called “SAM-conversion”.

   Note that Kawa can also infer the parameter and return types of a
method that overrides a method in a super-class.


File: kawa.info,  Node: Enumerations,  Next: Annotations,  Prev: Anonymous classes,  Up: Objects Classes and Modules

19.3 Enumeration types
======================

An enumeration type is a set of named atomic enumeration values that are
distinct from other values.  You define the type using ‘define-enum’,
and you reference enumeration values using colon notation:
     (define-enum colors (red blue green))
     (define favorite-color colors:green)
   Displaying an enum just prints the enum name, but readable output
using ‘write’ (or the ‘~s’ ‘format’ specifier) prepends the type name:
     (format "~a" favorite-color) ⇒ "green"
     (format "~s" favorite-color) ⇒ "colors:green"
   The static ‘values’ method returns a Java array of the enumeration
values, in declaration order, while ‘ordinal’ yields the index of an
enumeration value:
     (colors:values) ⇒ [red blue green]
     ((colors:values) 1) ⇒ blue
     (favorite-color:ordinal) ⇒ 2
   If you invoke the enumeration type as a function, it will map the
name (as a string) to the corresponding value.  (This uses the ‘valueOf’
method.)
     (colors "red") ⇒ red
     (colors "RED") ⇒ throws IllegalArgumentException
     (eq? favorite-color (colors:valueOf "green")) ⇒ #t

   Kawa enumerations are based on Java enumerations.  Thus the above is
similar to a Java5 ‘enum’ declaration, and the type ‘colors’ above
extends ‘java.lang.Enum’.

 -- Syntax: define-enum enum-type-name OPTION-PAIR... ‘(’enum-value-name
          ...‘)’ FIELD-OR-METHOD-DECL...
     This declares a new enumeration type ENUM-TYPE-NAME, whose
     enumerations values are the ENUM-VALUE-NAME list.  You can specify
     extra options and members using OPTION-PAIR and
     FIELD-OR-METHOD-DECL, which are as in ‘define-simple-class’.  (The
     DEFINE-ENUM syntax is similar to a ‘define-simple-class’ that
     extends ‘java.lang.Enum’.)

   (Note that R6RS has a separate Enumerations library ‘(rnrs enum)’.
Unfortunately, this is not compatible with standard Java enums.  R6RS
enums are simple symbols, which means you cannot distinguish two enum
values from different enumeration types if they have the same value, nor
from a vanilla symbol.  That makes them less useful.)


File: kawa.info,  Node: Annotations,  Next: Module classes,  Prev: Enumerations,  Up: Objects Classes and Modules

19.4 Annotations of declarations
================================

The Java platform lets you associate with each declaration zero or more
annotations
(http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html).
They provide an extensible mechanism to associate properties with
declarations.  Kawa support for annotations is not complete (the most
important functionality missing is being able to declare annotation
types), but is fairly functional.  Here is a simple example illustrating
use of JAXB annotations (http://jcp.org/en/jsr/detail?id=222): an
‘XmlRootElement’ annotation on a class, and an ‘XmlElement’ annotation
on a field:
     (import (class javax.xml.bind.annotation XmlRootElement XmlElement))
     (define-simple-class Bib ( ) (@XmlRootElement name: "bib")
       (books (@XmlElement name: "book" type: Book) ::java.util.ArrayList))
     (define-simple-class Book () ...)

   This tutorial
(http://per.bothner.com/blog/2011/Using-JAXB-annotations) explains the
JAXB example in depth.

   Here is the syntax:
     ANNOTATION ::= ‘(@’ANNOTATION-TYPENAME ANNOTATIONS-ELEMENT-VALUES‘)’
     ANNOTATIONS-ELEMENT-VALUES ::= ANNOTATION-ELEMENT-VALUE
       | ANNOTATION-ELEMENT-PAIR ...
     ANNOTATION-ELEMENT-PAIR ::= KEYWORD ANNOTATION-ELEMENT-VALUE
     ANNOTATION-ELEMENT-VALUE ::= EXPRESSION
     ANNOTATION-TYPENAME ::= EXPRESSION

   An ANNOTATIONS-ELEMENT-VALUES consisting of just a single
ANNOTATION-ELEMENT-VALUE is equivalent to an ANNOTATION-ELEMENT-PAIR
with a ‘value:’ keyword.

   Each KEYWORD must correspond to the name of an element (a
zero-argument method) in the annotation type.  The corresponding
ANNOTATION-ELEMENT-VALUE must be compatible with the element type
(return type of the method) of the annotation type.

   Allowed element types are of the following kinds:
   • Primitive types, where the ANNOTATION-ELEMENT-VALUE must be number
     or boolean coercible to the element type.
   • Strings, where the ANNOTATION-ELEMENT-VALUE is normally a string
     literal.
   • Classes, where the ANNOTATION-ELEMENT-VALUE is normally a
     classname.
   • Enumeration types.  The value usually has the form
     ‘CLASSNAME:ENUMFIELDNAME’.
   • Nested annotation types, where the ANNOTATION-ELEMENT-VALUE must be
     a compatible ANNOTATION value.
   • An array of one of the allowable types.  An array constructor
     expression works, but using the square bracket syntax is
     recommended.

   Annotations are usually used in declarations, where they are required
to be “constant-folded” to compile-time constant annotation values.
This is so they can be written to class files.  However, in other
contexts an annotation can be used as an expression with general
sub-expressions evaluated at run-time:
     (define bk-name "book")
     (define be (@XmlElement name: bk-name type: Book))
     (be:name) ⇒ "book"
   (This may have limited usefulness: There are some bugs, including
lack of support for default values for annotation elements.  These bugs
can be fixed if someone reports a need for runtime construction of
annotation values.)


File: kawa.info,  Node: Module classes,  Next: Importing,  Prev: Annotations,  Up: Objects Classes and Modules

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

Modules provide a way to organize Scheme into reusable parts with
explicitly defined interfaces to the rest of the program.  A “module” is
a set of definitions that the module “exports”, as well as some
“actions” (expressions evaluated for their side effect).  The top-level
forms in a Scheme source file compile a module; the source file is the
“module source”.  When Kawa compiles the module source, the result is
the “module class”.  Each exported definition is translated to a public
field in the module class.

19.5.1 Name visibility
----------------------

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

   If there is a ‘module-export’ (or ‘export’) declaration in the
module, then only those names listed are exported.  There can be more
than one ‘module-export’, and they can be anywhere in the Scheme file.
The recommended style has a single ‘module-export’ near the beginning of
the file.

 -- Syntax: module-export EXPORT-SPEC^{*}
 -- Syntax: export EXPORT-SPEC^{*}
     The forms ‘export’ and ‘module-export’ are equivalent.  (The older
     Kawa name is ‘module-export’; ‘export’ comes from R7RS.) Either
     form specifies a list of identifiers which can be made visible to
     other libraries or programs.
          EXPORT-SPEC ::= IDENTIFIER
            | ‘(rename’ IDENTIFIER_{1} IDENTIFIER_{2}‘)’
     In the former variant, an IDENTIFIER names a single binding defined
     within or imported into the library, where the external name for
     the export is the same as the name of the binding within the
     library.  A ‘rename’ spec exports the binding defined within or
     imported into the library and named by IDENTIFIER_{1}, using
     IDENTIFIER_{2} as the external name.

     Note that it is an error if there is no definition for IDENTIFIER
     (or IDENTIFIER_{1}) in the current module, or if it is defined
     using ‘define-private’.

     As a matter of style, ‘export’ or ‘module-export’ should appear
     after ‘module-name’ but _before_ other commands (including ‘import’
     or ‘require’).  (This is a requirement if there are any cycles.)

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

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

19.5.2 R7RS explicit library modules
------------------------------------

A R7RS ‘define-library’ form is another way to create a module.  The
R7RS term “library” is roughly the same as a Kawa module.  In Kawa, each
source file is a *note “implicit module”: implicit library, which may
contain zero or more explicit sub-modules (in the form of
‘define-library’) optionally followed by the definitions and expressions
of the implicit (file-level) module.

 -- Syntax: define-library LIBRARY-NAME LIBRARY-DECLARATION^{*}
     LIBRARY-NAME ::= ‘(’ LIBRARY-NAME-PARTS ‘)’
     LIBRARY-NAME-PARTS ::= IDENTIFIER^{+}

   A LIBRARY-NAME is a list whose members are identifiers and exact
non-negative integers.  It is used to identify the library uniquely when
importing from other programs or libraries.  Libraries whose first
identifier is ‘scheme’ are reserved for use by the R7RS report and
future versions of that report.  Libraries whose first identifier is
‘srfi’ are reserved for libraries implementing Scheme Requests for
Implementation (http://srfi.schemer.org/).  It is inadvisable, but not
an error, for identifiers in library names to contain any of the
characters ‘|’ ‘\’ ‘?’  ‘*’ ‘<’ ‘"’ ‘:’ ‘>’ ‘+’ ‘[’ ‘]’ ‘/’ ‘.’ or
control characters after escapes are expanded.

   See *note module-name:: for how a LIBRARY-NAME is mapped to a class
name.

     LIBRARY-DECLARATION ::=
       EXPORT-DECLARATION
       | IMPORT-DECLARATION
       | ‘(begin’ STATEMENT^{*} ‘)’
       | ‘(include’ FILENAME^{+}‘)’
       | ‘(include-ci’ FILENAME^{+}‘)’
       | ‘(include-library-declarations’ FILENAME^{+}‘)’
       | ‘(cond-expand’ COND-EXPAND-CLAUSE^{*} [‘(else’ command-or-definition*‘)’]‘)’
       | STATEMENT

   The ‘begin’, ‘include’, and ‘include-ci’ declarations are used to
specify the body of the library.  They have the same syntax and
semantics as the corresponding expression types.  This form of ‘begin’
is analogous to, but not the same as regular ‘begin’.  A plain STATEMENT
(which is allowed as a Kawa extension) is also part of the body of the
library, as if it were wrapped in a ‘begin’).

   The ‘include-library-declarations’ declaration is similar to
‘include’ except that the contents of the file are spliced directly into
the current library definition.  This can be used, for example, to share
the same ‘export’ declaration among multiple libraries as a simple form
of library interface.

   The ‘cond-expand’ declaration has the same syntax and semantics as
the ‘cond-expand’ expression type, except that it expands to spliced-in
library declarations rather than expressions enclosed in ‘begin’.

   When a library is loaded, its expressions are executed in textual
order.  If a library’s definitions are referenced in the expanded form
of a program or library body, then that library must be loaded before
the expanded program or library body is evaluated.  This rule applies
transitively.  If a library is imported by more than one program or
library, it may possibly be loaded additional times.

   Similarly, during the expansion of a library ‘(foo)’, if any syntax
keywords imported from another library ‘(bar)’ are needed to expand the
library, then the library ‘(bar)’ must be expanded and its syntax
definitions evaluated before the expansion of ‘(foo)’.

   Regardless of the number of times that a library is loaded, each
program or library that imports bindings from a library must do so from
a single loading of that library, regardless of the number of import
declarations in which it appears.  That is, ‘(import (only (foo) a’))
followed by ‘(import (only (foo) b))’ has the same effect as ‘(import
(only (foo) a b))’.

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

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

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

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

     If the form LIBRARY-NAME is used, then the class name is the result
     of taking each IDENTIFIER in the LIBRARY-NAME-PARTS, *note
     mangling: Mangling. if needed, and concatenating them separated by
     periods.  For example ‘(org example doc-utils)’ becomes
     ‘org.example.doc-utils’.  (You can’t reference the class name
     ‘doc-utils’ directly in Java, but the JVM has no problems with it.
     In Java you can use reflection to access classes with such names.)

     As a matter of style, ‘module-name’ should be the first command in
     a file (after possible comments).  It must appear before a
     ‘require’ or ‘import’, in case of cycles.

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

 -- Syntax: module-extends class
     Specifies that the class generated from the immediately surrounding
     module should extend (be a sub-class of) the class ‘CLASS’.

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

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

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

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

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

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

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

19.5.4 Same class for module and defined class
----------------------------------------------

You can declare a class using ‘define-simple-class’ with the same name
as the module class, for example the following in a file named
‘foo.scm’:
     (define-simple-class foo ...)
   In this case the defined class will serve dual-purpose as the module
class.

   To avoid confusion, in this case you must not specify
‘module-extends’, ‘module-implements’, or ‘(module-static #t)’.  Also,
the defined class should not have public static members.  In that case
it works out pretty well: public static members represent bindings
exported by the module; other non-private members “belong” to the
defined class.

   In this case ‘(module-static 'init-run)’ is implied.

19.5.5 Static vs non-static modules
-----------------------------------

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

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

   You can control whether a module is compiled to a static or a
non-static class using either a command-line flag to the compiler, or
using the ‘module-static’ special form.

‘--module-static’
     Generate a static module (as if ‘(module-static #t)’ were
     specified).  This is (now) the default.
‘--module-nonstatic’
‘--no-module-static’
     Generate a non-static module (as if ‘(module-static #f)’ were
     specified).  This used to be the default.
‘--module-static-run’
     Generate a static module (as if ‘(module-static 'init-run)’ were
     specified).

 -- Syntax: module-static name ...
 -- Syntax: module-static ‘#t’
 -- Syntax: module-static ‘#f’
 -- Syntax: module-static ‘'init-run’
     Control whether the generated fields and methods are static.  If
     ‘#t’ or ‘'init-run’ is specified, then the module will be a static
     module, _all_ definitions will be static.  If ‘'init-run’ is
     specified, in addition the module body is evaluated in the class’s
     static initializer.  (Otherwise, it is run the first time it is
     ‘require’’d.)  Otherwise, the module is an instance module.  If
     there is a non-empty list of NAMEs then the module is an instance
     module, but the NAMEs that are explicitly listed will be compiled
     to static fields and methods.  If ‘#f’ is specified, then all
     exported names will be compiled to non-static (instance) fields and
     methods.

     By default, if no ‘module-static’ is specified:
       1. If there is a ‘module-extends’ or ‘module-implements’
          declaration, or one of the ‘--applet’ or ‘--servlet’
          command-line flags was specified, then ‘(module-static #f)’ is
          implied.
       2. If one of the command-line flags ‘--no-module-static’,
          ‘--module-nonstatic’, ‘--module-static’, or
          ‘--module-static-run’ was specified, then the default is ‘#f’,
          ‘#f’, ‘#t’, or ‘'init-run’, respectively.
       3. If the module class is *note dual-purpose: dual-purpose-class.
          then ‘(module-static 'init-run)’ is implied.
       4. Otherwise the default is ‘(module-static #t)’.  (It used to be
          ‘(module-static #f)’ in older Kawa versions.)

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

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

19.5.6 Module options
---------------------

Certain compilation options can be be specified _either_ on the
command-line when compiling, or in the module itself.

 -- Syntax: module-compile-options [key‘:’ value] ...
     This sets the value of the ‘key’ option to ‘value’ for the current
     module (source file).  It takes effect as soon it is seen during
     the first macro-expansion pass, and is active thereafter (unless
     overridden by ‘with-compile-options’).

     The KEY: is one of the supported option names (The ending colon
     makes it a Kawa keyword).  Valid option keys are:

        • ‘main:’ - Generate an application, with a main method.

        • ‘full-tailcalls:’ - Use a calling convention that supports
          proper tail recursion.

        • ‘warn-undefined-variable:’ - Warn if no compiler-visible
          binding for a variable.

        • ‘warn-unknown-member:’ - Warn if referencing an unknown method
          or field.

        • ‘warn-invoke-unknown-method:’ - Warn if invoke calls an
          unknown method (subsumed by warn-unknown-member).

        • ‘warn-unused:’ - Warn if a variable is usused or code never
          executed.

        • ‘warn-uninitialized:’ - Warn if accessing an uninitialized
          variable.

        • ‘warn-unreachable:’ - Warn if this code can never be executed.
        • ‘warn-void-used:’ - Warn if an expression depends on the value
          of a void sub-expression (one that never returns a value).
        • ‘warn-as-error:’ - Treat a compilation warning as if it were
          an error.

     The VALUE must be a literal value: either a boolean (‘#t’ or ‘#f’),
     a number, or a string, depending on the KEY.  (All the options so
     far are boolean options.)

          (module-compile-options warn-undefined-variable: #t)
          ;; This causes a warning message that y is unknown.
          (define (func x) (list x y))

 -- Syntax: with-compile-options [key: value] ... body
     Similar to ‘module-compile-options’, but the option is only active
     within BODY.

     The module option key ‘main:’ has no effect when applied to a
     particular body via the ‘with-compile-options’ syntax.

          (define (func x)
            (with-compile-options warn-invoke-unknown-method: #f
              (invoke x 'size)))


File: kawa.info,  Node: Importing,  Next: Record types,  Prev: Module classes,  Up: Objects Classes and Modules

19.6 Importing from a library
=============================

You can import a module into the current namespace with ‘import’ or
‘require’.  This adds the exported bindings (or a subset of them) to the
current lexical scope.  It follows that these bindings (which are said
to be imported) are determined at compile-time.

 -- Syntax: import IMPORT-SET^{*}
     An ‘import’ declaration provides a way to import identifiers
     exported by a library (module).  Each IMPORT-SET names a set of
     bindings from a library and possibly specifies local names for the
     imported bindings.
          IMPORT-SET ::=
              CLASSNAME
            | LIBRARY-REFERENCE
            | ‘(library’ LIBRARY-REFERENCE ‘)’
            | ‘(class’ CLASS-PREFIX IMPORT-ONLY-NAME^{*}‘)’
            | ‘(only’ IMPORT-SET IMPORT-ONLY-NAME^{*}‘)’
            | ‘(except’ IMPORT-SET IDENTIFIER^{*}‘)’
            | ‘(prefix’ IMPORT-SET IDENTIFIER ‘)’
            | ‘(rename’ IMPORT-SET RENAME-PAIR^{*}‘)’
          LIBRARY-REFERENCE ::= ‘(’ LIBRARY-NAME-PARTS [EXPLICIT-SOURCE-NAME]‘)’
          IMPORT-ONLY-NAME ::= IDENTIFIER|RENAME-PAIR
          EXPLICIT-SOURCE-NAME ::= STRING
          RENAME-PAIR ::= ‘(’ IDENTIFIER_{1} IDENTIFIER_{2}‘)’

     A LIBRARY-REFERENCE is mapped to a class name by concatenating all
     the identifiers, separated by dots.  For example:
          (import (gnu kawa slib srfi37))
     is equivalent to:
          (import gnu.kawa.slib.srfi37)
     as well as to:
          (require gnu.kawa.slib.srfi37)

     By default, all of an imported library’s exported bindings are made
     visible within an importing library using the names given to the
     bindings by the imported library.  The precise set of bindings to
     be imported and the names of those bindings can be adjusted with
     the ‘only’, ‘except’, ‘prefix’, and ‘ rename’ forms as described
     below.

        • An ‘only’ form produces a subset of the bindings from another
          IMPORT-SET, including only the listed IDENTIFIERs.  The
          included IDENTIFIERs must be in the original IMPORT-SET.  If a
          RENAME-PAIR is used, then the ‘IDENTIFIER_{1}’ must be in the
          original IMPORT-SET, and is renamed to ‘IDENTIFIER_{2}’.  For
          example:
               (import (only (kawa example) A (B1 B2) C (D1 D2)))
          is equivalent to:
               (import (rename (only (kawa example) A B1 C D1)
                               (B1 B2) (D1 D2)))
          The names ‘A’, ‘B1’, ‘C’, and ‘D1’ must exist in the library
          ‘(kawa example)’.  The bindings are accessible using the names
          ‘A’, ‘B2’, ‘C’, and ‘D2’.

        • An ‘except’ form produces a subset of the bindings from
          another IMPORT-SET, including all but the listed IDENTIFIERs.
          All of the excluded IDENTIFIERs must be in the original
          IMPORT-SET.

        • A ‘prefix’ form adds the IDENTIFIER prefix to each name from
          another IMPORT-SET.

        • A ‘rename’ form:
               (rename (IDENTIFIER_{1} IDENTIFIER_{2}) ...)
          removes the bindings for ‘IDENTIFIER_{1} ...’ to form an
          intermediate IMPORT-SET, then adds the bindings back for the
          corresponding ‘IDENTIFIER_{2} ...’ to form the final
          IMPORT-SET.  Each ‘IDENTIFIER_{1}’ must be in the original
          IMPORT-SET, each IDENTIFIER_{2} must not be in the
          intermediate IMPORT-SET, and the IDENTIFIER_{2}s must be
          distinct.

     A ‘class’ form is a convenient way to define abbreviations for
     class names; it may be more convenient than ‘define-alias’.  The
     CLASS-PREFIX is concatenated with each IDENTIFIER (with a period in
     between) to produce a classname.  Each IDENTIFIER becomes an alias
     for the class.  For example:
          (import (class java.util Map (HashMap HMap)))
     This defines ‘Map’ as an alias for ‘java.util.Map’, and ‘HMap’ as
     an alias for ‘java.util.HashMap’.  (You can think of the ‘class’
     form as similar to a ‘only’ form, where the CLASS-PREFIX names a
     special kind of library represented of a Java package, and whose
     exported bindings are the classes in the package.)

     You can combine the ‘class’ form with ‘only’, ‘except’, ‘rename’,
     and ‘prefix’, though only ‘prefix’ is likely to be useful.  For
     example:
          (import (prefix (class java.lang Long Short) jl-))
     is equivalent to
          (import (class java.lang (Long jl-Long) (Short jl-Short)))
     which is equivalent to:
          (define-private-alias jl-Short java.lang.Short)
          (define-private-alias jl-Long java.lang.Long)

 -- Syntax: require ‘’’featureName
 -- Syntax: require classname [EXPLICIT-SOURCE-NAME]
 -- Syntax: require EXPLICIT-SOURCE-NAME]
     Search for a matching module (class), and add the names exported by
     that module to the current set of visible names.  Normally, the
     module is specified using CLASSNAME.

     The form ‘require’ has similar functionality as ‘import’, but with
     a different syntax, and without options like ‘rename’.

     If a ‘"SOURCEPATH"’ is specified then that is used to locate the
     source file for the module, and if necessary, compile it.

     If a ‘'FEATURENAME’ is specified then the FEATURENAME is looked up
     (at compile time) in the "feature table" which yields the
     implementing CLASSNAME.

 -- Syntax: provide ‘’’featurename
     Declare that ‘'FEATURENAME’ is available.  A following
     ‘cond-expand’ in this scope will match FEATURENAME.

   Using ‘require’ and ‘provide’ with FEATURENAMEs is similar to the
same-named macros in SLib, Emacs, and Common Lisp.  However, in Kawa
these are not functions, but instead they are syntax forms that are
processed at compile time.  That is why only quoted FEATURENAMEs are
supported.  This is consistent with Kawa emphasis on compilation and
static binding.

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

19.6.1 Searching for modules
----------------------------

When Kawa sees a ‘import’ or ‘require’ it searches for either a matching
source file or a previously-compiled class with a matching name.

   For ‘import’ we generate a classname by converting it in the same way
‘module-name’ does: taking each identifier in the LIBRARY-NAME-PARTS,
mangling if needed, and concatenating the parts separated by periods.

   If there is a matching module in any PROGRAM-UNIT that is in the
process of being compiled, we use that.  This may be a file requested to
be compiled with the ‘-C’ command-line switch, or an extra
LIBRARY-DEFINITION in a file already parsed.  Kawa will attempt to
finish compiling the module and load the class, but if there are
circular dependencies it will use the uncompiled definitions.

   Next Kawa looks for a matching class in the context classpath.
(There is special handling if the library-name starts with ‘srfi’, and
certain builtin classes will have ‘kawa.lib.’ prepended.)

   Kawa also searches for a matching source file, described below.  It
uses the implicit source name (formed by concatenating the library-name
parts, separated by ‘"/"’), as well as any EXPLICIT-SOURCE-NAME.  The
source file is parsed as a PROGRAM-UNIT.  It is an error if the
PROGRAM-UNIT does not declare a library (explicit or implicit) with the
matching name.

   If Kawa finds both a matching source file and a class, it will pick
one based on which is newer.

19.6.2 Searching for source files
---------------------------------

The Java property ‘kawa.import.path’ controls how ‘import’ and ‘require’
search for a suitable source file.  Example usage:
     $ kawa -Dkawa.import.path=".:<foo fo>/opt/fo-libs/*.scm:/usr/local/kawa"

   The value of the ‘kawa.import.path’ property is a list of path
elements, separated by ‘":"’.  Each path element is combined with either
the explicit source name or the implicit source name to produce a
filename.  If a matching file exists, then we have found a source file.

   If a path element contains a ‘"*"’ then the ‘"*"’ is replaced by the
implicit source name (without an extension).  (Any explicit source name
is ignored in this case.)  For example, for ‘(import (foo bar))’ or
‘(require foo.bar)’ the implicit source name is ‘"foo/bar"’.  If the
path element is ‘"/opt/kawa/*.sc"’ then the resulting filename is
‘"/opt/kawa/foo/bar.sc"’.

   If there is no ‘"*"’ in the path element, and there is an explicit
source, then it is appended to the path element (or replaces the path
element if the explicit source is absolute).  Otherwise we use the
implicit source, followed by the default file extension.  (The default
file extension is that of the current source if that is a named file;
otherwise the default for the current language, which is ‘".scm"’ for
Scheme.)

   A path element that starts with a selector of the form
‘"<LIBRARY-NAME-PARTS>"’ is only applicable if a prefix of the requested
module name matches the LIBRARY-NAME-PARTS.  If there is ‘"*"’ in the
path element, that is replaced by the corresponding rest of the implicit
source name.  For example if importing ‘(fee fo foo fum’) and the path
element is ‘"<fee fo>/opt/fo-libs/*.scm"’ then the resulting filename is
‘"/opt/fo-libs/foo/fum.scm"’.  If there is a selector but no ‘"*"’, then
the rest of the path element following the selector is combined with the
explicit or implicit source as if there were no selector (assuming of
course that the selector matches).

   If the resulting filename is relative, then it is resolved relative
to the “current root”.  For example the source to a library with the
name ‘(x y)’ that compiles to a class ‘x.y’ might be a file named
‘/a/b/x/y.scm’.  Then the current root would be ‘/a/b/’ - that is the
directory that results from removing the library name suffix from the
file name.

   More generally: assume the current module has N name components.  For
example the name ‘(x y)’ (with the class name ‘x.y’) has 2 components.
The current root is what you get when you take the current file name
(say ‘"/a/b/c/d.scm"’), and remove everything after the N’th slash
(‘"/"’) from the end (say ‘"c/d.scm"’; what remains (e.g.  ‘"/a/b/"’ is
the current root.  (If the current input source is not a named file, use
the value of ‘(current-path)’ with a ‘"/"’ appended.)

   The default search path is ‘"."’ - i.e.  just search relative to the
current root.

19.6.3 Builtin libraries
------------------------

The following libraries are bundled with Kawa:

‘(scheme base)’
‘(scheme case-lambda)’
‘(scheme char)’
‘(scheme complex)’
‘(scheme cxr)’
‘(scheme cxr)’
‘(scheme eval)’
‘(scheme inexact)’
‘(scheme lazy)’
‘(scheme load)’
‘(scheme process-context)’
‘(scheme read)’
‘(scheme repl)’
‘(scheme time)’
‘(scheme write)’
‘(scheme r5rs)’
     The above are standard libraries as defined by R7RS.
‘(rnrs arithmetic bitwise)’
‘(rnrs hashtables)’
‘(rnrs lists)’
‘(rnrs programs)’
‘(rnrs sorting)’
‘(rnrs unicode)’
     The above are standard libraries as defined by R6RS.
‘(kawa reflect)’
     Defines procedures and syntax for acessing Java objects and
     members: ‘as’ ‘field’ ‘instance?’  ‘invoke’ ‘invoke-static’
     ‘invoke-special’ ‘make’ ‘primitive-throw’ ‘set-field!’
     ‘set-static-field!’  ‘static-field’
‘(kawa expressions)’
‘(kawa hashtable)’
‘(kawa quaternions)’
‘(kawa rotations)’
‘(kawa regex)’
‘(kawa string-cursors)’
     Various Kawa libraries add details.
‘(kawa base)’
     All the bindings by default available to the kawa top-level.

19.6.4 Importing a SRFI library
-------------------------------

Importing a supported SRFI numbered N is conventionally doing using a
‘(import (srfi N))’ or the older R6RS syntax ‘(import (srfi :N))’ (with
a colon, for historical reasons).  You can also give it a name, as
specified by SRFI 95 (http://srfi.schemers.org/srfi-95/srfi-95.html).
For example, any of these work:
     (import (srfi 95))
     (import (srfi 95 sorting-and-merging))
     (import (srfi :95))
     (import (srfi :95 sorting-and-merging))
   You can also use ‘(require 'srfi-N)’:
     (require 'srfi-95)

19.6.5 Importing from a plain class
-----------------------------------

Note you can import from many classes, even if they weren’t compiled
from a library-definition.  The set of ‘public’ fields in a class are
considered as the set of exported definitions, with the names demangled
as needed.

   The module can be static module (all public fields must be static),
or an instance module (it has a public default constructor).

   If an imported definition is a non-static field and if no module
instance for that class has been registered in the current environment,
then a new instance is created and registered (using a "magic"
identifier).  If the module class either inherits from
‘gnu.expr.ModuleBody’ or implements ‘java.lang.Runnable’ then the
corresponding ‘run’ method is executed.  (This is done _after_ the
instance is registered so that cycles can be handled.)  These actions
(creating, registering, and running the module instance) are done both
at compile time and at run time, if necessary.

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


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

19.7 Record types
=================

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

   Kawa compiles the record type into a nested class.  If the
‘define-record-type’ appears at module level, the result is a class that
is a member of the module class.  For example if the above ‘pare’ class
is define in a module ‘parelib’, then the result is a class named ‘pare’
with the internal JVM name ‘parelib$pare’.  The ‘define-record-type’ can
appear inside a procedure, in which case the result is an inner class.

   The nested class has 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 resulting functions, without
needing to use run-time reflection.


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

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

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

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

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

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

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

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

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

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

 -- Procedure: 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: Method operations,  Next: Allocating objects,  Prev: Dynamic records,  Up: Objects Classes and Modules

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

You can call a Java method as if it were a Scheme procedure using
various mechanisms.

19.9.1 Calling static methods using colon notation
--------------------------------------------------

The easiest way to invoke a static method is to use *note colon
notation: Colon notation, specifically:
     ‘(’CLASS-EXPRESSION‘:’METHOD-NAME ARGUMENT ...‘)’

   The CLASS-EXPRESSION can be a class in the current lexical scope,
such as a class defined using ‘define-simple-class’:
     (define-simple-class MyClass ()
       ((add2 x y) allocation: 'static (+ x y)))
     (MyClass:add2 3 4) ⇒ 7

   Often CLASS-EXPRESSION is a fully-qualified class name:
     (java.lang.Math:sqrt 9.0) ⇒ 3.0

   This is only allowed when the name is of a class that exists and is
accessible both at compile-time and run-time, and the name is not
otherwise lexically bound.

   You can also use a defined alias:
     (define-alias jlMath java.lang.Math)
     (jlMath:sqrt 16.0) ⇒ 4.0

   You can even evaluate CLASS-EXPRESSION at run-time (in which case
Kawa may have to use slower reflection):
     (let ((math java.lang.Math)) (math:sqrt 9.0)) ⇒ 3.0

   Here ‘java.lang.Math’ evaluates to a ‘java.lang.Class’ instance for
the named class (like Java’s ‘java.lang.Class.class’, again assuming the
class exists and is accessible both at compile-time and run-time, and
the name is not otherwise lexically bound.

19.9.2 Calling instance methods using colon notation
----------------------------------------------------

The syntax is:
     ‘(’INSTANCE‘:’METHOD-NAME ARGUMENT ...‘)’
   This invokes the method named METHOD-NAME with the evaluated INSTANCE
as the target object and the evaluated ARGUMENTs as the method
arguments.

   For example:
     ((list 9 8 7):toString) ⇒ "(9 8 7)"
     ([5 6 7]:get 2) ⇒ 7

   This older syntax is also available:
     ‘(*:’METHOD-NAME INSTANCE ARGUMENT ...‘)’

   For example:
     (*:toString (list 9 8 7))

   You can also name the class explicitly:
     ‘(’CLASS-EXPRESSION‘:’METHOD-NAME INSTANCE ARGUMENT ...‘)’
   For example:
     (java.util.List:get [5 6 7] 2) ⇒ 7
   Using an explicit class is like coercing the INSTANCE:
     ‘(*:’METHOD-NAME ‘(as ’CLASS-EXPRESSION INSTANCE ‘)’ARGUMENT ...‘)’

   Note that for some special values, including ‘java.lang.Class’
instances, you can’t use the compact form of *note colon notation: Colon
notation. where the INSTANCE is before the comma:
     (java.lang.Integer:getDeclaredField "MAX_VALUE") ⇒ error
   This is because in this case we look for a static member of
‘java.lang.Integer’ (at least as currently defined and implemented),
while we want an instance member of ‘java.lang.Class’.  In those cases
you can use one of these alternative forms, which all return the same
‘java.lang.reflect.Field’ result:
     (*:getDeclaredField java.lang.Integer "MAX_VALUE")
     (java.lang.Class:getDeclaredField java.lang.Integer "MAX_VALUE")
     (invoke java.lang.Integer 'getDeclaredField "MAX_VALUE")

19.9.3 Method names
-------------------

The method to invoke is selected using the specified method name and
argments.  If specified name is not a Java name, it is "mangled" (*note
Mangling::) into a valid Java name.  All accessible methods whose names
match are considered.  Methods that match after appending ‘$V’ or ‘$X’
or ‘$V$X’ are also considered.  A ‘$V’ suffix matches a variable number
of arguments: any excess arguments are collect into an ‘gnu.lists.LList’
or a Java array (depending on the final parameter type).  A ‘$X’
specifies that the method expects an extra implicit ‘CallContext’
parameter.  In that case the method’s result is written to the
‘CallContext’, so the method result type must be ‘void’.

   (Kawa may compile a procedure with a ‘#!rest’ or keyword args whose
name is ‘FN’ to a method named ‘FN$V’.  It adds an implicit parameter
for the extra arguments.  By default this extra extra parameter is a
Scheme list.  You can specify a Java array type instead, in which case
the method is named ‘FN’ without the ‘$V’, and instead it is marked as a
Java-5 varargs method.  The array element type must be compatible with
all the extra arguments.)

19.9.4 Invoking a method with the ‘invoke’ function
---------------------------------------------------

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

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

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

     An example:
          (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.

 -- Procedure: invoke object name args ...
     The NAME can be ‘<symbol>’ or ‘<string>’ that names one or more
     methods in the Java class.

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

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

 -- Procedure: invoke-special class receiver-object name arg ...
     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.

     This procedure is very similar to ‘invoke’ and ‘invoke-static’ and
     invokes the specified method, ignoring any methods in subclasses
     that might overide it.  One interesting use is to invoke a method
     in your super-class like the Java language ‘super’ keyword.

     Any methods in the specified CLASS that match "NAME" or "NAME$V"
     collectively form a generic procedure.  That generic procedure is
     then applied as in ‘invoke’ using the ‘receiver-object’ and the
     arguments (if any).

     The compiler must be able to inline this procedure (because you
     cannot force a specific method to be called using reflection).
     Therefore the CLASS and NAME must resolve at compile-time to a
     specific method.

          (define-simple-class <MyClass> (<java.util.Date>)
            ((get-year) :: <int>
             (+ (invoke-special <java.util.Date> (this) 'get-year)) 1900)
            ((set-year (year :: <int>)) :: <void>
             (invoke-special <java.util.Date> (this) 'set-year (- year 1900))))

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

19.9.5 Using a namespace prefix
-------------------------------

_This way of invoking a method is deprecated._

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

   Instead of a VAMESPACE-URI you can use a variable that names a class,
usually of the form ‘<CLASSNAME>’.  The following is equivalent to the
above:
     (define-namespace Int32 <java.lang.Integer>)
   However, there is one important difference: The ‘<CLASSNAME>’ is
first searched in the lexical scope.  It may resolve to a class defined
in the current compilation unit (perhaps defined using
‘define-simple-class’), or imported from another module, or an alias
(such as from ‘define-alias’).  Only if ‘<CLASSNAME>’ is _not_ found in
the current scope is it tried as the class name CLASSNAME.

   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
String ‘"ff"’.

   The general syntax is
     (PREFIX:METHOD-NAME ARG ...)
   This invokes the method named METHOD-NAME in the class corresponding
to PREFIX, and the ARGs are the method arguments.

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

   You can also call instance methods using a namespace prefix:
     (Int32:doubleValue (Int32:new "00255"))
   This returns the ‘double’ value ‘255.0’.

   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 a known class, then Kawa will automatically
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.

   As a final shorthand you can use an identifier in handle brackets,
such as an existing type alias like ‘<list>’.  The following are all
equivalent:
     (<list>:list3 'a 'b 'c)
   This is equivalent to:
     (define-namespace PREFIX <list>
     (PREFIX:list3 'a 'b 'c)
   for some otherwise-unused PREFIX.


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

19.10 Allocating objects
========================

The recommended way to create an instance of a type T is to “call” T as
if it were a function, with the arguments used to initialize the object.
If ‘T’ is a class and ‘T’ has a matching constructor, then the arguments
will used for constructor arguments:
     (java.util.StringTokenizer "this/is/a/test" "/")
   (You can think of the type T as being coerced to an
instance-constructor function.)

   If ‘T’ is a container or collection type, then typically the
arguments will be used to specify the child or component values.  Many
standard Scheme procedures fit this convention.  For example in Kawa
‘list’ and ‘vector’ evaluate to types, rather than procedures as in
standard Scheme, but because types can be used as constructor functions
it just works:
     (list 'a (+ 3 4) 'c) ⇒ (a 7 c)
     (vector 'a 'b 'c) ⇒ #(a b c)
   Any class ‘T’ that has a default constructor and an ‘add’ method can
be initialized this way.  Examples are ‘java.util’ collection classes,
and ‘jawa.awt’ and ‘javax.swing’ containers.
     (java.util.ArrayList 11 22 33) ⇒ [11, 22, 333]
   The above expression is equivalent to:
     (let ((tmp (java.util.ArrayList)))
       (tmp:add 11)
       (tmp:add 22)
       (tmp:add 33)
       tmp)

   Allocating Java arrays (*note Creating-new-Java-arrays::) uses a
similar pattern:
     (int[] 2 3 5 7 11)

   Sometimes you want to set some named property to an initial value.
You can do that using a keyword argument.  For example:
     (javax.swing.JButton text: "Do it!" tool-tip-text: "do it")

   This is equivalent to using “setter methods”:
     (let ((tmp (javax.swing.JButton)))
       (tmp:setText "Do it!")
       (tmp:setToolTipText "do it")
       tmp)

   A keyword argument ‘KEY-NAME’‘:’ can can translated to either a
‘setKEYNAME:’ or a ‘addKEYNAME:’ method.  The latter makes it convenient
to add listeners:

     (javax.swing.JButton
       text: "Do it!"
       action-listener:
        (object (java.awt.event.ActionListener)
          ((actionPerformed e) (do-the-action))))
   This is equivalent to:
     (let ((tmp (javax.swing.JButton)))
       (tmp:setText "Do it!")
       (tmp:addActionListener
         (object (java.awt.event.ActionListener)
           ((actionPerformed e) (do-the-action))))
       tmp)

   Making use of so-called “SAM-conversion” (*note SAM-conversion::)
makes it even more convenient:
     (javax.swing.JButton
       text: "Do it!"
       action-listener:
        (lambda (e) (do-the-action)))

   The general case allows for a mix of constructor arguments, property
keywords, and child values:
     CLASS-TYPE CONSTRUCTOR-VALUE... PROPERTY-INITIALIZER... CHILD-VALUE...
     CONSTRUCTOR-VALUE ::= EXPRESSION
     PROPERTY-INITIALIZER ::= KEYWORD EXPRESSION
     CHILD-VALUE ::= EXPRESSION

   First an object is constructed with the CONSTRUCTOR-VALUE arguments
(if any) passed to the object constructor; then named properties (if
any) are used to initialize named properties; and then remaining
arguments are used to add child values.

   There is an ambiguity if there is no PROPERTY-INITIALIZER - we can’t
distinguish between a CONSTRUCTOR-VALUE and a CHILD-VALUE.  In that
case, if there is a matching constructor method, then all of the
arguments are constructor arguments; otherwise, there must a default
constructor, and all of the arguments are CHILD-VALUE arguments.

   There is a trick you can you if you need both CONSTRUCTOR-VALUE and
CHILD-VALUE arguments: separate them with an “empty keyword” ‘||:’.
This matches a method named ‘add’, which means that the next argument
effectively a CHILD-VALUE - as do all the remaining arguments.  Example:
     (let ((vec #(1 2 3)))
       (java.util.ArrayList vec ||: 4 5 6))
       ⇒ [1, 2, 3, 4, 5, 6]

   The compiler rewrites these allocations expression to generated
efficient bytecode, assuming that the “function” being applied is a type
known by the compiler.  Most of the above expressions also work if the
type is applied at run-time, in which case Kawa has to use slower
reflection:
     (define iarr int[])
     (apply iarr (list 3 4 5)) ⇒ [3 4 5]
   However ‘addXXX’ methods and SAM-conversion are currently only
recognized in the case of a class known at compile-time, not at
run-time.

   Here is a working Swing demo illustrating many of these techniques:

     (import (class javax.swing
                    JButton Box JFrame))
     (define-simple-class HBox (Box)
       ((*init*) (invoke-special Box (this) '*init* 0)))

     (define value 0)

     (define txt
       (javax.swing.JLabel
        text: "0"))

     (define (set-value i)
       (set! value i)
       (set! txt:text (number->string i)))

     (define fr
       (JFrame
          title: "Hello!"
          (Box 1#|VERTICAL|# ||:
           (javax.swing.Box:createGlue)
           txt
           (javax.swing.Box:createGlue)
           (HBox
            (JButton ;; uses 1-argument constructor
     	"Decrement" ;; constructor argument
     	tool-tip-text: "decrement"
     	action-listener: (lambda (e) (set-value (- value 1))))
            (javax.swing.Box:createGlue)
            (JButton ;; uses 0-argument constructor
     	text: "Increment"
     	tool-tip-text: "increment"
     	action-listener: (lambda (e) (set-value (+ value 1))))))))
     (fr:setSize 200 100)
     (set! fr:visible #t)

   If you prefer, you can use the older ‘make’ special function:

 -- Procedure: 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>’.
     Equivalent to:
          TYPE ARGS ...

   Another (semi-deprecated) function is to use the colon notation with
the ‘new’ pseudo-function.  The following three are all equivalent:
     (java.awt.Point:new x: 4 y: 3)
     (make java.awt.Point: x: 4 y: 3)
     (java.awt.Point x: 4 y: 3)


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

19.11 Accessing object fields
=============================

19.11.1 Accessing static fields and properties
----------------------------------------------

The recommmended way to access fields uses the *note colon notation:
Colon notation.  For static fields and properties the following is
recommended:
     CLASS-EXPRESSION‘:’FIELD-NAME
   For example:
     java.lang.Integer:MAX_VALUE

   A property with a ‘get’ method is equivalent to a field.  The
following are all equivalent:
     java.util.Currency:available-currencies
     java.util.Currency:availableCurrencies
     (java.util.Currency:getAvailableCurrencies)

   Just like for a method call, the CLASS-EXPRESSION can be a class in
the current lexical scope, a fully-qualified class name, or more
generally an expression that evaluates to a class.

19.11.2 Accessing instance fields and properties
------------------------------------------------

The syntax is:
     INSTANCE‘:’FIELD-NAME

   The FIELD-NAME can of course be the name of an actual object field,
but it can also be the name of a property with a zero-argument ‘get’
method.  For example, if ‘cal’ is a ‘java.util-Calendar’ instance, then
the following are all equivalent:
     cal:time-zone
     cal:timeZone
     (cal:getTimeZone)
     (cal:get-time-zone)

   You can use colon notation to assign to a field:
     (set! cal:time-zone TimeZone:default)
   which is equivalent to:
     (cal:setTimeZone (TimeZone:getDefault))

   A Java array only has the ‘length’ field, plus the ‘class’ property:
     (int[] 4 5 6):length ⇒ 3
     (int[] 4 5 6):class:name ⇒ "int[]"

19.11.3 Using field and static-field methods
--------------------------------------------

The following methods are useful in cases where colon notation is
ambiguous, for example where there are both fields and methods with the
same name.  You might also prefer as a matter of style, to emphasise
that a field is being accessed.

 -- Procedure: field object fieldname
     Get the instance field with the given FIELDNAME from the given
     OBJECT.  Returns the value of the field, which must be accessible.
     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"’ (or
     ‘"isFIELDNAME"’ for a boolean property).

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

 -- Procedure: 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 accessible.  This
     procedure has a ‘setter’, and so can be used as the first operand
     to ‘set!’.

     If the FIELDNAME is the special name ‘class’, then it returns the
     ‘java.lang.Class’ object corresponding to CLASS (which is usually a
     ‘gnu.bytecode.ClassType’ object).

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

 -- Procedure: slot-ref object fieldname
     A synonym for ‘(field OBJECT FIELDNAME)’.

 -- Procedure: slot-set! object fieldname value
     A synonym for ‘(set! (field OBJECT FIELDNAME) VALUE)’.

19.11.4 Older colon-dot notation
--------------------------------

There is older syntax where following the colon there is field name a
following the colon _and_ a period.

   To access an static field named FIELD-NAME use this syntax
     (PREFIX:.FIELD-NAME INSTANCE)
   The PREFIX can be as discussed in *Note Method operations::.  Here
are 5 equivalent ways:
     (java.lang.Integer:.MAX_VALUE)
     (<java.lang.Integer>:.MAX_VALUE)
     (define-namespace Int32 <java.lang.Integer>)
     (Int32:.MAX_VALUE)
     (define-namespace Integer "class:java.lang.Integer")
     (Integer:.MAX_VALUE)
     (define-alias j.l.Integer java.lang.Integer)
     (j.l.Integer:.MAX_VALUE)
   You can set a static field using this syntax:
     (set! (PREFIX:.FIELD-NAME) NEW-VALUE)

   The special field name ‘class’ can be used to extract the
‘java.lang.Class’ object for a class-type.  For example:
     (java.util.Vector:.class) ⇒ class java.util.Vector

   To access a instance field named FIELD-NAME use the following syntax.
Note the period before the FIELD-NAME.
     (*:.FIELD-NAME INSTANCE)
   This syntax works with ‘set!’ - to set the field use this syntax:
     (set! (*:.FIELD-NAME INSTANCE) NEW-VALUE)
   Here is an example:
     (define p (list 3 4 5))
     (*:.cdr p) ⇒ (4 5)
     (set! (*:.cdr p) (list 6 7))
     p ⇒ (3 6 7)

   You can specify an explicit class:
     (PREFIX:.FIELD-NAME INSTANCE)
   If PREFIX is bound to ‘<CLASS>’, then the above is equivalent to:
     (*:.FIELD-NAME (as <CLASS> INSTANCE))


File: kawa.info,  Node: Mangling,  Next: Scheme types in Java,  Prev: Field operations,  Up: Objects Classes and Modules

19.12 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.  Traditionally, 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.  Names in the Java language can
contain upper- and lower-case letters, digits, and the special symbols
‘_’ and ‘$’.  The Java virtual machine (JVM) allows most characters, but
still has some limitations.

   Kawa translates class names, package names, field names, and local
variable names using the ”symbolic” convention
(https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm), so
most characters are unchanged.  For example the Scheme function
‘file-exists?’ becomes the field ‘file-exists?’, but ‘dotted.name’
becomes ‘dotted\,name’.  Such names may not be valid Java name, so to
access them from a Java program you might have to use reflection.

   When translating procedure names to method names, Kawa uses a
different translation, in order to achieve more “Java-like” names.  This
means translating a Scheme-style name like ‘make-temporary-file’ to
"mixed-case" words, such as ‘makeTemporaryFile’.  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.Mangling’ class for the full list.
Characters that do not have a mnemonic abbreviation are mangled as ‘$’
followed by a four-hex-digit unicode value.  For example ‘Tamil vowel
sign ai’ is mangled as ‘$0bc8’.

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


File: kawa.info,  Node: Scheme types in Java,  Next: Array operations,  Prev: Mangling,  Up: Objects Classes and Modules

19.13 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 ‘gnu.lists.FString’.
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 ‘gnu.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 ‘gnu.math.DFloNum’.

   A Scheme pair is implemented by ‘gnu.lists.Pair’.

   A Scheme vector is implemented by ‘gnu.lists.FVectror’.

   Scheme characters are implemented using ‘gnu.text.Char’.

   Scheme strings are implemented using ‘gnu.lists.FString’.

   Scheme procedures are all sub-classes of ‘gnu.mapping.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’.


File: kawa.info,  Node: Array operations,  Next: Loading Java functions into Scheme,  Prev: Scheme types in Java,  Up: Objects Classes and Modules

19.14 Using Java Arrays
=======================

19.14.1 Creating new Java arrays
--------------------------------

To allocate a Java array you can use the array type specifier as a
constructor function.  For example, to allocate an array with room for
10 elements each of each is a primitive ‘int’:
     (int[] length: 10)

   You can specify the initial elements instead of the length:
     (object[] 31 32 33 34)
   This creates a 4-length array, initialized to the given values.

   Note this is a variation of the generation object-allocation (*note
Allocating objects::) pattern.  You can explicitly use the ‘make’
function, if you prefer:
     (make object[] 31 32 33 34)

   If you specify a length, you can also specify initial values for
selected elements.  If you specify an index, in the form of a literal
integer-valued keyword, then following elements are placed starting at
that position.
     (int[] length: 100 10 12 80: 15 16 50: 13 14)
   This creates an array with 100 elements.  Most of them are
initialized to the default value of zero, but elements with indexes 0,
1, 50, 51, 80, 81 are initialized to the values 10, 12, 13, 14, 15, 16,
respectively.

19.14.2 Accessing Java array elements
-------------------------------------

You can access the elements of a Java array by treating it as a
one-argument function, where the argument is the index:
     (define primes (integer[] 2 3 5 7 11 13))
     (primes 0) ⇒ 2
     (primes 5) ⇒ 13

   You can set an element by treating the array as a function with a
‘setter’:
     (set! (primes 0) -2)
     (set! (primes 3) -7)
     primes ⇒ [-2 3 5 -7 11 13]

   To get the number of elements of an array, you can treat it as having
a ‘length’ field:
     primes:length ⇒ 6

   Here is a longer example.  This is the actual definition of the
standard ‘gcd’ function.  Note the ‘args’ variable receives all the
arguments on the form of an ‘integer’ array.  (This uses the Java5
varargs feature.)
     (define (gcd #!rest (args ::integer[])) ::integer
       (let ((n ::int args:length))
         (if (= n 0)
     	0
     	(let ((result ::integer (args 0)))
     	  (do ((i ::int 1 (+ i 1)))
     	      ((>= i n) result)
     	    (set! result (gnu.math.IntNum:gcd result (args i))))))))

   The above example generates good code, thanks to judicious use of
casts and type specifications.  In general, if Kawa knows that a
“function” is an array then it will generate efficient bytecode
instructions for array operations.

19.14.3 Old low-level array macros
----------------------------------

The deprecated *note Low-level array macros:: are also supported.


File: kawa.info,  Node: Loading Java functions into Scheme,  Next: Evaluating Scheme expressions from Java,  Prev: Array operations,  Up: Objects Classes and Modules

19.15 Loading Java functions into Scheme
========================================

When ‘kawa -C’ compiles (*note Files compilation::) a Scheme module it
creates a class that implements the ‘java.lang.Runnable’ interface.
(Usually it is a class that extends the ‘gnu.expr.ModuleBody’.)  It is
actually fairly easy to write similar "modules" by hand in Java, which
is useful when you want to extend Kawa with new "primitive functions"
written in Java.  For each function you need to create an object that
extends ‘gnu.mapping.Procedure’, and then bind it in the global
environment.  We will look at these two operations.

   There are multiple ways you can create a ‘Procedure’ object.  Below
is a simple example, using the ‘Procedure1’ class, which is class
extending ‘Procedure’ that can be useful for one-argument procedure.
You can use other classes to write procedures.  For example a
‘ProcedureN’ takes a variable number of arguments, and you must define
‘applyN(Object[] args)’ method instead of ‘apply1’.  (You may notice
that some builtin classes extend ‘CpsProcedure’.  Doing so allows has
certain advantages, including support for full tail-recursion, but it
has some costs, and is a bit trickier.)

     import gnu.mapping.*;
     import gnu.math.*;
     public class MyFunc extends Procedure1
     {
       // An "argument" that is part of each procedure instance.
       private Object arg0;

       public MyFunc(String name, Object arg0)
       {
         super(name);
         this.arg0 = arg0;
       }

       public Object apply1 (Object arg1)
       {
         // Here you can so whatever you want. In this example,
         // we return a pair of the argument and arg0.
         return gnu.lists.Pair.make(arg0, arg1);
       }
     }

   You can create a ‘MyFunc’ instance and call it from Java:
       Procedure myfunc1 = new MyFunc("my-func-1", Boolean.FALSE);
       Object aresult = myfunc1.apply1(some_object);
   The name ‘my-func-1’ is used when ‘myfunc1’ is printed or when
‘myfunc1.toString()’ is called.  However, the Scheme variable
‘my-func-1’ is still not bound.  To define the function to Scheme, we
can create a "module", which is a class intended to be loaded into the
top-level environment.  The provides the definitions to be loaded, as
well as any actions to be performed on loading

     public class MyModule
     {
       // Define a function instance.
       public static final MyFunc myfunc1
         = new MyFunc("my-func-1", IntNum.make(1));
     }

   If you use Scheme you can use ‘require’:
     #|kawa:1|# (require <MyModule>)
     #|kawa:2|# (my-func-1 0)
     (1 0)

   Note that ‘require’ magically defines ‘my-func-1’ without you telling
it to.  For each public final field, the name and value of the field are
entered in the top-level environment when the class is loaded.  (If
there are non-static fields, or the class implements ‘Runnable’, then an
instance of the object is created, if one isn’t available.)  If the
field value is a ‘Procedure’ (or implements ‘Named’), then the name
bound to the procedure is used instead of the field name.  That is why
the variable that gets bound in the Scheme environment is ‘my-func-1’,
not ‘myfunc1’.

   Instead of ‘(require <MyModule>)’, you can do ‘(load "MyModule")’ or
‘(load "MyModule.class")’.  If you’re not using Scheme, you can use
Kawa’s ‘-f’ option:
     $ kawa -f MyModule --xquery --
     #|kawa:1|# my-func-1(3+4)
     <list>1 7</list>

   If you need to do some more complex calculations when a module is
loaded, you can put them in a ‘run’ method, and have the module
implement ‘Runnable’:

     public class MyModule implements Runnable
     {
       public void run ()
       {
         Interpreter interp = Interpreter.getInterpreter();
         Object arg = Boolean.TRUE;
         interp.defineFunction (new MyFunc ("my-func-t", arg));
         System.err.println("MyModule loaded");
       }
     }

   Loading ‘MyModule’ causes ‘"MyModule loaded"’ to be printed, and
‘my-func-t’ to be defined.  Using ‘Interpreter’’s ‘defineFunction’
method is recommended because it does the righ things even for languages
like Common Lisp that use separate "namespaces" for variables and
functions.

   A final trick is that you can have a ‘Procedure’ be its own module:

     import gnu.mapping.*;
     import gnu.math.*;
     public class MyFunc2 extends Procedure2
     {
       public MyFunc(String name)
       {
         super(name);
       }

       public Object apply2 (Object arg1, arg2)
       {
         return gnu.lists.Pair.make(arg1, arg2);
       }

       public static final MyFunc myfunc1 = new MyFunc("my-func-2);
     }


File: kawa.info,  Node: Evaluating Scheme expressions from Java,  Prev: Loading Java functions into Scheme,  Up: Objects Classes and Modules

19.16 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: void Scheme.registerEnvironment ()
     Initializes the Scheme environment.  Maybe needed if you try to
     load a module compiled from a Scheme source file.

 -- 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()’.  Before you start, you need to initialize the
global environment, which you can do with
     Environment.setCurrent(new Scheme().getEnvironment());

   Alternatively, rather than setting the global environment, you can
use this style:
     Scheme scm = new Scheme();
     Object x = scm.eval("(+ 3 2)");
     System.out.println(x);

19.16.1 Using ‘javax.script’ portable Java scripting
----------------------------------------------------

Kawa also supports the standard ‘javax.script’
(http://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html)
API. The main advantage of this API is if you want your users to be able
to choose between multiple scripting languages.  That way you can
support Kawa without Kawa-specific programming.

   For example the standard JDK tool jrunscript
(http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jrunscript.html)
provides a read-eval-print-loop for any language that implements the
‘javax.script’ API. It knows nothing about Kawa but can still use it:
     $ jrunscript -cp kawa.jar -l scheme
     scheme> (cadr '(3 4 5))
     4

   (Of course the ‘jrunscript’ REPL isn’t as nice as the one that Kawa
provides.  For example the latter can handle multi-line inputs.)


File: kawa.info,  Node: XML tools,  Next: Miscellaneous,  Prev: Objects Classes and Modules,  Up: Top

20 Working with XML and HTML
****************************

Kawa has a number of features for working with XML, HTML, and generated
web pages.

   In Kawa you don’t write XML or HTML directly.  Instead you write
expressions that evaluate to “node objects” corresponding to elements,
attributes, and text.  You then write these node objects using either an
XML or HTML format.

   Many web-page-generating tools require you to work directly with raw
HTML, as for example:
     (display "<p>Don't use the <code>&lt;blink&gt;</code> tag.</p>")

   In Kawa you would instead do:
     (display (html:p "Don't use the " (html:code "<blink>") " tag."))

   The conversion from node objects to XML or HTML is handled by the
formatter (or serializer).  Some advantages of doing it this way are:
   • You don’t have to worry about quoting special characters.  Missing
     or incorrect quoting is a common source of bugs and security
     problems on systems that work directly with text, such as PHP.
   • Some errors, such as mismatched element tags, are automatically
     avoided.
   • The generated XML can be validated as it is generated, or even
     using compile-time type-checking.  (Kawa doesn’t yet do either.)
   • In an application that also reads XML, you can treat XML that is
     read in and XML that is generated using the same functions.

* Menu:

* Formatting XML::
* Creating HTML nodes::
* Creating XML nodes::
* XML literals::
* Server-side scripts::  Writing web-server-side Kawa scripts
* Self-configuring page scripts::
* Servlets::             Installing Kawa programs as Servlets
* CGI scripts::          Installing Kawa programs as CGI scripts
* HTTP requests::        Functions for accessing HTTP requests
* HTTP response::        Functions for generating HTTP response
* XML beyond Scheme::    Using non-Scheme languages for XML/HTML


File: kawa.info,  Node: Formatting XML,  Next: Creating HTML nodes,  Up: XML tools

20.1 Formatting XML
===================

The easiest way to generate HTML or XML output is to run Kawa with the
appropriate *note ‘--output-format’ option: Named output formats.

   The intentation is that these output modes should be compatible with
XSLT 2.0 and XQuery 1.0 Serialization
(http://www.w3.org/TR/2006/PR-xslt-xquery-serialization-20061121/).
(However, that specifies many options, most of which have not yet been
implemented.

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

   To illustrate:
     $ kawa --output-format html
     #|kawa:1|# (html:img src:"img.jpg")
     <img src="img.jpg">
     $ kawa --output-format xhtml
     #|kawa:1|# (html:img src:"img.jpg")
     <img xmlns="http://www.w3.org/1999/xhtml" src="img.jpg" />
     $ kawa --output-format xml
     #|kawa:1|# (html:img src:"img.jpg")
     <img xmlns="http://www.w3.org/1999/xhtml" src="img.jpg"></img>
   And here is the default ‘scheme’ formatting:
     $ kawa
     #|kawa:1|# (html:img src:"img.jpg")
     ({http://www.w3.org/1999/xhtml}img src: img.jpg )

 -- Procedure: as-xml value
     Return a value (or multiple values) that when printed will print
     VALUE in XML syntax.
          (require 'xml)
          (as-xml (make-element 'p "Some " (make-element 'em "text") "."))
     prints ‘<p>Some <em>text</em>.</p>’.

 -- Procedure: unescaped-data data
     Creates a special value which causes ‘data’ to be printed, as is,
     without normal escaping.  For example, when the output format is
     XML, then printing ‘"<?xml?>"’ prints as ‘&lt;?xml?&gt;’, but
     ‘(unescaped-data "<?xml?>")’ prints as ‘<?xml?>’.

