3. Program structure
R5RS discusses how to structure programs. Everything which is defined in Section 5 of R5RS applies also to STklos. To make things shorter, this aspects will not be described here (see R5RS for complete information).
STklos modules can be used to organize a program into separate environments (or name spaces). Modules provide a clean way to organize and enforce the barriers between the components of a program.
STklos provides a simple module system which is largely inspired from the one of Tung and Dybvig exposed in Tung and Dybvig paper [TuD96]. As their modules system, STklos modules are defined to be easily used in an interactive environment.
STklos syntax
Define-module
evaluates the expressions <expr1>
, <expr2>
… which
constitute the body of the module <name>
in the environment of that module.
Name
must be a valid symbol. If this symbol has not already been used to
define a module, a new module, named name
, is created.
Otherwise, the expressions <expr1>
, <expr2>
… are evaluated in
the environment of the (old) module <name>
[1]
Definitions done in a module are local to the module and do not interact with the definitions in other modules. Consider the following definitions,
(define-module M1
(define a 1))
(define-module M2
(define a 2)
(define b (* 2 x)))
Here, two modules are defined and they both bind the symbol a
to a
value. However, since a
has been defined in two distinct modules
they denote two different locations.
The STklos
module, which is predefined, is a special module which
contains all the global bindings of a R5RS program. A symbol
defined in the STklos
module, if not hidden by a local definition, is
always visible from inside a module. So, in the previous exemple, the
x
symbol refers the x
symbol defined in the STklos
module.
The result of define-module
is void.
STklos procedure
Returns the current module.
(define-module M
(display
(cons (eq? (current-module) (find-module 'M))
(eq? (current-module) (find-module 'STklos))))) |- (#t . #f)
STklos procedure
STklos modules are first class objects and find-module
returns the
module associated to name
if it exists. If there is no module
associated to name
, an error is signaled if no default
is
provided, otherwise find-module
returns default
.
STklos procedure
Returns #t
if object
is a module and #f
otherwise.
(module? (find-module 'STklos)) => #t
(module? 'STklos) => #f
(module? 123 'no) => no
STklos syntax
Specifies the symbols which are exported (i.e. visible outside
the current module). By default, symbols defined in a module are not
visible outside this module, excepted if they appear in an export
clause.
If several export
clauses appear in a module, the set of
exported symbols is determined by "unionizing" symbols exported
in all the export
clauses.
The result of export
is void.
STklos syntax
Specifies the modules which are imported by the current module. Importing a module makes the symbols it exports visible to the importer, if not hidden by local definitions. When a symbol is exported by several of the imported modules, the location denoted by this symbol in the importer module correspond to the one of the last module in the list
(<module1> <module2> ...)
which exports it.
If several import
clauses appear in a module, the set of
imported modules is determined by appending the various list of modules
in their apparition order.
(define-module M1
(export a b)
(define a 'M1-a)
(define b 'M1-b))
(define-module M2
(export b c d)
(define b 'M2-b)
(define c 'M2-c)
(define d 'M2-d))
(define-module M3
(import M1 M2)
(display (list a b c d))) |- (M1-a M2-b M2-c M2-d)
(define-module M4
(import M2 M1)
(display (list a b c d))) |- (M1-a M1-b M2-c M2-d)
It is also possible to import partially (i.e. not all exported symbols) from a module, as shown below:
(define-module M5
(import (M2 c d) M1)
(display (list a b c d))) |- (M1-a M1-b M2-c M2-d)
In this case, only the symbols c
and d
are imported from
module M2
.
Importations are not "transitive": when the module -C_ imports the module B which is an importer of module A the symbols of A are not visible from C, except by explicitly importing the A module from C. |
The module STklos , which contains the global variables
is always implicitly imported from a module. Furthermore,
this module is always placed at the end of the list of imported modules.
|
STklos syntax
Changes the value of the current module to the module with the given name
.
The expressions evaluated after select-module
will take place in
module name
environment. Module name
must have been created
previously by a define-module
. The result of select-module
is
void.
Select-module
is particularly useful when debugging since it
allows to place toplevel evaluation in a particular module. The
following transcript shows an usage of select-module
.
[2]):
stklos> (define foo 1)
stklos> (define-module bar
(define foo 2))
stklos> foo
1
stklos> (select-module bar)
bar> foo
2
bar> (select-module stklos)
stklos>
STklos procedure
Returns the value bound to symbol
in module
. If symbol
is not bound,
an error is signaled if no default
is provided, otherwise symbol-value
returns default
.
STklos procedure
Returns the value bound to symbol
in module
. If symbol
is not bound,
an error is signaled if no default
is provided, otherwise symbol-value
returns default
.
Note that this function searches the value of symbol
in module
and in the STklos module if module is not a R7RS library.
STklos procedure
Returns the name (a symbol) associated to a module
.
STklos procedure
Returns the list of modules that module
(fully) imports.
STklos procedure
Returns the list of symbols exported by module
. Note that this function
returns the list of symbols given in the module export
clause and that
some of these symbols can be not yet defined.
STklos procedure
Returns the list of symbols already defined in module
.
STklos procedure
Returns the list of all the living modules.
STklos syntax
This form returns the value of symbol with name s
in the module with name
mod
. If this symbol is not bound, an error is signaled if no default
is
provided, otherwise in-module
returns default
. Note that the value of s
is searched in mod
and all the modules it imports.
This form is in fact a shortcut. In effect,
(in-module my-module foo)
is equivalent to
(symbol-value* 'foo (find-module 'my-module))