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). Eachimport-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
1identifier
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
, andrename
forms as described below.
An
only
form produces a subset of the bindings from anotherimport-set
, including only the listedidentifier
s. The includedidentifier
s must be in the originalimport-set
. If arename-pair
is used, then themust be in the original
identifier
1import-set
, and is renamed to. For example:
identifier
2(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
, andD1
must exist in the library(kawa example)
. The bindings are accessible using the namesA
,B2
,C
, andD2
.An
except
form produces a subset of the bindings from anotherimport-set
, including all but the listedidentifier
s. All of the excludedidentifier
s must be in the originalimport-set
.A
prefix
form adds theidentifier
prefix to each name from anotherimport-set
.A
rename
form:(rename (identifier
1identifier
2) …)removes the bindings for
to form an intermediate
identifier
1 …import-set
, then adds the bindings back for the correspondingto form the final
identifier
2 …import-set
. Eachmust be in the original
identifier
1import-set
, eachidentifier
2 must not be in the intermediateimport-set
, and theidentifier
2s must be distinct.A
class
form is a convenient way to define abbreviations for class names; it may be more convenient thandefine-alias
. Theclass-prefix
is concatenated with eachidentifier
(with a period in between) to produce a classname. Eachidentifier
becomes an alias for the class. For example:(import (class java.util Map (HashMap HMap)))This defines
Map
as an alias forjava.util.Map
, andHMap
as an alias forjava.util.HashMap
. (You can think of theclass
form as similar to aonly
form, where theclass-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 withonly
,except
,rename
, andprefix
, though onlyprefix
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
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 asimport
, but with a different syntax, and without options likerename
.If a
is specified then that is used to locate the source file for the module, and if necessary, compile it.
"
sourcepath
"
If a
'
is specified then thefeaturename
featurename
is looked up (at compile time) in the "feature table" which yields the implementingclassname
.
Declare that
'
is available. A followingfeaturename
cond-expand
in this scope will matchfeaturename
.
Using require
and provide
with featurename
s 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 featurename
s 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.
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.
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 "<
is only applicable if a prefix
of the requested module name matches the library-name-parts
>"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.
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.
Importing a supported SRFI numbered N
is conventionally
doing using a (import (srfi
or the older R6RS syntax N
))(import (srfi :
(with a colon, for historical reasons). You can also give it
a name, as specified by SRFI 95. For example, any of these work:
N
))
(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)
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).