Chapter 13. The Module System and the Module Compiler

Table of Contents
Introduction and Terminology
Organization of a Module
Compilation and its Semantics

Introduction and Terminology

It is good practice to divide a large program into smaller units that can be independently understood. Such units are called modules. RScheme has full support for modules.

Traditionally, there are two different purposes of modules. The first and least interesting purpose is to function as a unit of compilation. Early versions of Fortran already supported separate compilation of this type of module. The second and most interesting purpose of a module is to encapsulate related data and functions with a restricted view from the outside. Typically, modules are used to hide implementation details of some abstract data type that can only be used by other modules (called the client modules) through a well-defined set of functions called the interface of the abstract data type.

In RScheme a module is both a unit of separate compilation and a unit of encapsulation. Currently, only the off-line compiler (or module compiler) rsc can create a module.

You may think of a module as an augmented top-level environment mapping names to variables, macros, or special forms (collectively called bindings). Bindings are not first-class objects so you cannot manipulate them the way you manipulate other RScheme objects such as numbers and strings. In addition to the collection of bindings, a module contains information about which bindings are visible from the outside (exported) and which bindings are purely local to the module. Finally, a module contains information about what other modules are needed by the module (called the imported modules).

When a module M imports a module N, the top-level environment of M is augmented with the name-to-binding mappings of N that are exported. RScheme provides functionality to give different names of these bindings from those used by N, so that both M and N share the same bindings, but under different names. This renaming is useful when you need to avoid name clashes between modules.

The collection of modules together with the imports relation in a program form a directed acyclic graph. In other words, it is not possible for modules to be mutually imported.