Using the module system
=======================

Scheme48 is deeply integrated with an advanced module system.  For complete detail of its module system, see Module system.  Briefly, however:

  * Packages are top-level environments suitable for evaluating expressions and definitions, either interactively, from files loaded on-the-fly, or as the bodies of modules.  They can also access bindings exported by structures by opening the structures.

  * Structures are libraries, or implementations of interfaces, exporting sets of bindings that packages can access. Underlying structures are usually packages, in which the user can, in some cases, interactively evaluate code during development.

Scheme48's usual development system, the command processor, provides a number of commands for working with the module system.  For complete details, see Module commands.  Chief among these commands are ,open and ,in.  ,open STRUCT ... makes all of the bindings from each of STRUCT ... available in the interaction environment.  Many of the sections in this manual describe one or more structures with the name they are given.  For example, in order to use, or open, the multi-dimensional array library in the current interaction environment, one would enter

     ,open arrays lisp

     to the command processor.  ,in STRUCT sets the
     interaction environment to be the package underlying STRUCT.
     For instance, if, during development, the user decides that the
     package of the existing structure foo should open the structure
     bar, he might type

          ,in foo
          ,open bar lisp

          The initial interaction environment is known as the user
          package; the interaction environment may be reverted to the user
          package with the ,user command.

          Module descriptions, or code in the Module configuration
          language, module configuration language should be loaded into the
          special environment for that language with the ,config command
          (see Module commands).  Eg, if packages.scm contains a
          set of module descriptions that the user wishes to load, among which
          is the definition of a structure frobozz which he wishes to
          open, he will typically send the following to the command processor
          prompt:

               ,config ,load packages.scm
               ,open frobozz lisp

               Note: These are commands for the interactive command
               processor, not special directives to store in files to work
               with the module system.  The module language is disjoint from Scheme;
               for complete detail on it, see Module system.

Configuration mutation
----------------------

(This section was derived from work copyrighted © 1993--2005 by Richard Kelsey, Jonathan Rees, and Mike Sperber.)

During program development, it is often desirable to make changes to packages and interfaces.  In static languages, it is usually necessary to re-compile and re-link a program in order for such changes to be reflected in a running system.  Even in interactive Common Lisp systems, a change to a package's exports often requires reloading clients that have already mentioned names whose bindings change.  In those systems, once read resolves a use of a name to a symbol, that resolution is fixed, so a change in the way that a name resolves to a symbol can be reflected only by re-reading all such references.

The Scheme48 development environment supports rapid turnaround in modular program development by allowing mutations to a program's configuration and giving a clear semantics to such mutation.  The rule is that variable bindings in a running program are always resolved according to the current structure and interface bindings, even when these bindings change as a result of edits to the configuration.  For example, consider the following:

     (define-interface foo-interface (export a c))
     (define-structure foo foo-interface
       (open scheme)
       (begin (define a 1)
              (define (b x) (+ a x))
              (define (c y) (* (b a) y))))
     (define-structure bar (export d)
       (open scheme foo)
       (begin (define (d w) (+ (b w) a)))) lisp

     This program has a bug.  The variable named b, which is free in
     the definition of d, has no binding in bar's package.
     Suppose that b was intended to be exported by foo, but
     was mistakenly omitted.  It is not necessary to re-process bar or
     any of foo's other clients at this point.  One need only change
     foo-interface and inform the development system of that change
     (using, say, an appropriate Emacs command), and foo's binding of
     b will be found when the procedure d is called and its
     reference to b actually evaluated.

     Similarly, it is possible to replace a structure; clients of the old
     structure will be modified so that they see bindings from the new one.
     Shadowing is also supported in the same way.  Suppose that a client
     package C opens a structure mumble that exports a name
     x, and mumble's implementation obtains the binding of
     x from some other structure frotz.  C will see the
     binding from frotz.  If one then alters mumble so that it
     shadows bar's binding of x with a definition of its own,
     procedures in C that refer to x will subsequently
     automatically see mumble's definition instead of the one from
     frotz that they saw earlier.

     This semantics might appear to require a large amount of computation on
     every variable reference: the specified behaviour appears to require
     scanning the package's list of opened structures and examining their
     interfaces --- on every variable reference evaluated, not just at
     compile-time.  However, the development environment uses caching with
     cache invalidation to make variable references fast, and most of the
     code is invoked only when the virtual machine traps due to a reference
     to an undefined variable.

Listing interfaces
------------------

The list-interfaces structure provides a utility for examining interfaces.  It is usually opened into the config package with ,config ,open list-interfaces in order to have access to the structures & interfaces easily.

 -- procedure: list-interface struct-or-interface returns unspecified
     Lists all of the bindings exported by STRUCT-OR-INTERFACE along with their Static type system, static types.  For example,

          > ,config ,open list-interfaces
          > ,config (list-interface condvars)
          condvar-has-value?        (proc (:condvar) :value)
          condvar-value             (proc (:condvar) :value)
          condvar?                  (proc (:value) :boolean)
          make-condvar              (proc (&rest :value) :condvar)
          maybe-commit-and-set-condvar! (proc (:condvar :value) :boolean)
          maybe-commit-and-wait-for-condvar (proc (:condvar) :boolean)
          set-condvar-has-value?!   (proc (:condvar :value) :unspecific)
          set-condvar-value!        (proc (:condvar :value) :unspecific) lisp