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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
|
@node Module configuration language
@section Module configuration language
@cindex configuration language
@cindex module language
Scheme48's module system is used through a @dfn{module configuration
language}. @emph{The configuration language is entirely separate from
Scheme.} Typically, in one configuration, or set of components that
compose a program, there is an @file{interfaces.scm} file that defines
all of the interfaces used by the configuration, and there is also a
@file{packages.scm} file that defines all of the packages & structures
that compose it. Note that modules are not necessarily divided into
files or restricted to one file: modules may include arbitrarily many
files, and modules' code may also be written in-line to structure
expressions (see the @code{begin} package clause below), although that
is usually only for expository purposes and trivial modules.
@cindex package clauses
Structures are always created with corresponding @dfn{package clauses}.
Each clause specifies an attribute of the package that underlies the
structure or structures created using the clauses. There are several
different types of clauses:
@cindex opening structures
@cindex structures, opening
@cindex accessing structures
@cindex structures, accessing
@stindex structure-refs
@bnindex structure-ref
@deffn {package clause} open structure @dots{}
@deffnx {package clause} access structure @dots{}
@code{Open} specifies that the package should open each of the listed
structures, whose packages will be loaded if necessary. @code{Access}
specifies that each listed structure should be accessible using the
@code{(structure-ref @var{structure} @var{identifier})} special form,
which evaluates to the value of @var{identifier} exported by the
accessed structure @var{structure}. @code{Structure-ref} is available
from the @code{structure-refs} structure. Each @var{structure} passed
to @code{access} is not opened, however; the bindings exported thereby
are available only using @code{structure-ref}. While the qualified
@code{structure-ref} mechanism is no longer useful in the presence of
modified structures (see below on @code{modify}, @code{subset}, &
@code{with-prefix}), some old code still uses it, and @code{access} is
also useful to force that the listed structures' packages be loaded
without cluttering the namespace of the package whose clauses the
@code{access} clause is among.
@end deffn
@deffn {package clause} for-syntax package-clause @dots{}
Specifies a set of package clauses for the next floor of the reflective
tower; @pxref{Macros in concert with modules}.
@end deffn
@deffn {package clause} files file-specifier @dots{}
@deffnx {package clause} begin code @dots{}
@code{Files} and @code{begin} specify the package's code. @code{Files}
takes a sequence of namelists for the filenames of files that contain
code; @pxref{Filenames}. @code{Begin} accepts in-line program code.
@end deffn
@cindex compiler optimization
@cindex optimizer
@deffn {package clause} optimize optimizer-specifier @dots{}
@deffnx {package clause} integrate [on?]
@code{Optimize} clauses request that specified compiler optimizers be
applied to the code. (Actually, `optimizer' is a misnomer. The
@code{optimize} clause may specify arbitrary passes that the compiler
can be extended with.)
@c @xref{Extending the compiler}.)
@code{Integrate} clauses specify whether or not integrable procedures
from other modules, most notably Scheme primitives such as @code{car}
or @code{vector-ref}, should actually be integrated in this package.
This is by default on. Most modules should leave it on for any
reasonable performance; only a select few, into which code is intended
to be dynamically loaded frequently and in which redefinition of
imported procedures is common, need turn this off. The value of the
argument to @code{integrate} clauses should be a literal boolean, @ie{}
@code{#t} or @code{#f}; if no argument is supplied, integration is
enabled by default.
@cindex @code{auto-integrate} optimizer
@cindex procedure integration
@cindex integrated procedures
@cindex in-line procedures
@cindex @code{flat-environments} optimizer
@cindex closure flattening
@cindex flat closures
@cindex environment flattening
@cindex flat environments
Currently, the only optimizer built-in to Scheme48 is the automatic
procedure integrator, or @code{auto-integrate}, which attempts stronger
type reconstruction than is attempted with most code (@pxref{Static
type system}) and selects procedures below a certain size to be made
integrable (so that the body will be compiled in-line in all known call
sites). Older versions of Scheme48 also provided another optimizer,
@code{flat-environments}, which would flatten certain lexical closure
environments, rather than using a nested environment structure. Now,
however, Scheme48's byte code compiler always flattens environments;
specifying @code{flat-environments} in an @code{optimize} clause does
nothing.
@end deffn
@cindex structure definition forms
A configuration is a sequence of definitions. There are definition
forms for only structures and interfaces.
@deffn {configuration form} define-structure name interface package-clause @dots{}
@deffnx {configuration form} define-structures ((name interface) @dots{}) package-clause @dots{}
@code{Define-structure} creates a package with the given package
clauses and defines @var{name} to be the single view atop it, with the
interface @var{interface}. @code{Define-structure} also creates a
package with the given package clauses; upon that package, it defines
each @var{name} to be a view on it with the corresponding interface.
@end deffn
@deffn {configuration form} define-module (name parameter @dots{}) definition @dots{} result
@deffnx {configuration form} def name @dots{} (parameterized-module argument @dots{})
@code{Define-module} defines @var{name} to be a parameterized module
that accepts the given parameters.
@end deffn
@cindex interface definition forms
@deffn {configuration form} define-interface name interface
Defines @var{name} to be the interface that @var{interface} evaluates
to. @var{Interface} may either be an interface constructor application
or simply a name defined to be an interface by some prior
@code{define-interface} form.
@end deffn
@cindex simple interfaces
@deffn {interface constructor} export export-specifier @dots{}
@code{Export} constructs a simple interface with the given export
specifiers. The export specifiers specify names to export and their
corresponding static types. Each @var{export-specifier} should have
one of the following forms:
@table @code
@item @var{symbol}
in which case @var{symbol} is exported with the most general value type;
@item (@var{symbol} @var{type})
in which case @var{symbol} is exported with the given type; or
@item ((@var{symbol} @dots{}) @var{type})
in which case each @var{symbol} is exported with the same given type
@end table
For details on the valid forms of @var{type}, @pxref{Static type
system}. @strong{Note:} All macros listed in interfaces @emph{must} be
explicitly annotated with the type @code{:syntax}; otherwise they would
be exported with a Scheme value type, which would confuse the compiler,
because it would not realize that they are macros: it would instead
treat them as ordinary variables that have regular run-time values.
@end deffn
@cindex compound interfaces
@deffn {interface constructor} compound-interface interface @dots{}
This constructs an interface that contains all of the export specifiers
from each @var{interface}.
@end deffn
@cindex anonymous structures
Structures may also be constructed anonymously; this is typically most
useful in passing them to or returning them from parameterized modules.
@deffn {structure constructor} structure interface package-clauses
@deffnx {structure constructor} structures (interface @dots{}) package-clauses
@code{Structure} creates a package with the given clauses and evaluates
to a structure over it with the given interface. @code{Structures}
does similarly, but it evaluates to a number of structures, each with
the corresponding @var{interface}.
@end deffn
@cindex modified structures
@cindex modified interfaces
@deffn {structure constructor} subset structure (name @dots{})
@deffnx {structure constructor} with-prefix structure name
@deffnx {structure constructor} modify structure modifier @dots{}
These modify the interface of @var{structure}. @code{Subset} evaluates
to a structure that exports only @var{name} @dots{}, excluding any
other names that @var{structure} exported. @code{With-prefix} adds a
prefix @var{name} to every name listed in @var{structure}'s interface.
Both @code{subset} and @code{with-prefix} are syntactic sugar for the
more general @code{modify}, which applies the modifier commands in a
strictly right-to-left or last-to-first order. @strong{Note:} These
all @emph{denote new structures with new interfaces}; they do not
destructively modify existing structures' interfaces.
@end deffn
@deffn {modifier command} prefix name
@deffnx {modifier command} expose name @dots{}
@deffnx {modifier command} hide name @dots{}
@deffnx {modifier command} alias (from to) @dots{}
@deffnx {modifier command} rename (from to) @dots{}
@code{Prefix} adds the prefix @var{name} to every exported name in the
structure's interface. @code{Expose} exposes only @var{name} @dots{};
any other names are hidden. @code{Hide} hides @var{name} @dots{}.
@code{Alias} exports each @var{to} as though it were the corresponding
@var{from}, as well as each @var{from}. @code{Rename} exports each
@var{to} as if it were the corresponding @var{from}, but it also hides
the corresponding @var{from}.
Examples:
@lisp
(modify @var{structure}
(prefix foo:)
(expose bar baz quux))@end lisp
@noindent
makes only @code{foo:bar}, @code{foo:baz}, and @code{foo:quux},
available.
@lisp
(modify @var{structure}
(hide baz:quux)
(prefix baz:)
(rename (foo bar)
(mumble frotz))
(alias (gargle mumph)))@end lisp
@noindent
exports @code{baz:gargle} as what was originally @code{mumble},
@code{baz:mumph} as an alias for what was originally @code{gargle},
@code{baz:frotz} as what was originally @code{mumble}, @code{baz:bar}
as what was originally @code{foo}, @emph{not} @code{baz:quux} --- what
was originally simply @code{quux} ---, and everything else that
@var{structure} exported, but with a prefix of @code{baz:}.
@end deffn
There are several simple utilities for binding variables to structures
locally and returning multiple structures not necessarily over the same
package (@ie{} not with @code{structures}). These are all valid in the
bodies of @code{define-module} and @code{def} forms, and in the
arguments to parameterized modules and @code{open} package clauses.
@deffn syntax begin body
@deffnx syntax let ((name value) @dots{}) body
@deffnx syntax receive (name @dots{}) producer body
@deffnx syntax values value @dots{}
These are all as in ordinary Scheme. Note, however, that there is no
reasonable way by which to use @code{values} except to call it, so it
is considered a syntax; also note that @code{receive} may not receive
a variable number of values --- @ie{} there are no `rest lists' ---,
because list values in the configuration language are nonsensical.
@end deffn
@cindex macros in the module configuration language
@cindex configuration language macros
@cindex module language macros
Finally, the configuration language also supports syntactic extensions,
or macros, as in Scheme.
@deffn {configuration form} define-syntax name transformer-specifier
Defines the syntax transformer @var{name} to be the transformer
specified by @var{transformer-specifier}. @var{Transformer-specifier}
is exactly the same as in Scheme code; it is evaluated as ordinary
Scheme.
@end deffn
|