1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
@node Module system architecture
@section Module system architecture
@cindex configuration language
@cindex module language
The fundamental mechanism by which Scheme code is evaluated is the
lexical environment. Scheme48's module system revolves around this
fundamental concept. Its purpose is to control the denotation of names
in code@footnote{This is in contrast to, for example, Common Lisp's
package system, which controls the mapping from strings to names.} in a
structured, modular manner. The module system is manipulated by a
static @dfn{configuration language}, described in the next section;
this section describes the concepts in the architecture of the module
system.
@cindex packages
@cindex structures
@cindex interfaces
@cindex modules
The @dfn{package} is the entity internal to the module system that
maps a set of names to denotations. For example, the package that
represents the Scheme language maps @code{lambda} to a descriptor for
the special form that the compiler interprets to construct a procedure,
@code{car} to the procedure that accesses the car of a pair, @etcT{}.
Packages are not explicitly manipulated by the configuration language,
but they lie underneath structures, which are described below. A
package also contains the code of a module and controls the visibility
of names within that code. It also includes some further information,
such as optimizer switches. A @dfn{structure} is a view on a package;
that is, it contains a package and an @dfn{interface} that lists all of
the names it exports to the outside. Multiple structures may be
constructed atop a single package; this mechanism is often used to offer
multiple abstraction levels to the outside. A @dfn{module} is an
abstract entity: it consists of some code, the namespace visible to the
code, and the set of abstractions or views upon that code.
@cindex opening structures
@cindex structures, opening
A package contains a list of the structures whose bindings should be
available in the code of that package. If a structure is referred to
in a such a list of a package, the package is said to @dfn{open} that
structure. It is illegal for a package to open two structures whose
interfaces contain the same name.@footnote{The current implementation,
however, does not detect this. Instead it uses the left-most structure
in the list of a package's @code{open} clause; see the next section for
details on this.} Packages may also modify the names of the bindings
that they import. They may import only selected bindings, exclude
certain bindings from structures, rename imported bindings, create
alias bindings, and add prefixes to names.
@stindex scheme
@stindex prescheme
Most packages will open the standard @code{scheme} structure, although
it is not implicitly opened, and the module system allows not opening
@code{scheme}. It may seem to be not very useful to not open it, but
this is necessary if some bindings from it are intended to be shadowed
by another structure, and it allows for entirely different languages
from Scheme to be used in a package's code. For example, Scheme48's
byte code interpreter virtual machine is implemented in a subset of
Scheme called Pre-Scheme, which is described in a later chapter in this
manual. The modules that compose the VM all open not the @code{scheme}
structure but the @emph{@code{prescheme}} structure. The configuration
language itself is controlled by the module system, too. In another
example, from Scsh, the Scheme shell, there is a structure @code{scsh}
that contains all of the Unix shell programming facilities. However,
the @code{scsh} structure necessarily modifies some of the bindings
related to I/O that the @code{scheme} structure exports. Modules could
not open both @code{scheme} and @code{scsh}, because they both provide
several bindings with the same names, so Scsh defines a more convenient
@code{scheme-with-scsh} structure that opens both @code{scheme}, but
with all of the shadowed bindings excluded, and @code{scsh}; modules
that use Scsh would open neither @code{scsh} nor @code{scheme}: they
instead open just @code{scheme-with-scsh}.
@cindex interface re@"use
@cindex compound interfaces
@cindex interface abstraction
Interfaces are separated from structures in order that they may be
re@"used and combined. For example, several different modules may
implement the same abstractions differently. The structures that they
include would, in such cases, re@"use the same interfaces. Also, it is
sometimes desirable to combine several interfaces into a @dfn{compound
interface}; see the @code{compound-interface} form in the next section.
Furthermore, during interactive development, interface definitions may
be reloaded, and the structures that use them will automatically begin
using the new interfaces; @pxref{Using the module system}.
@cindex parameterized modules
@cindex generic modules
@cindex higher-order modules
@cindex functors
Scheme48's module system also supports @dfn{parameterized modules}.
Parameterized modules, sometimes known as @dfn{generic modules},
@dfn{higher-order modules} or @dfn{functors}, are essentially functions
at the module system level that map structures to structures. They may
be instantiated or applied arbitrarily many times, and they may accept
and return arbitrarily many structures. Parameterized modules may also
accept and return other parameterized modules.
|