This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Module documentation



Hi.  Can someone please translate the following into proper english
and then send it to whoever maintains the guile documentation?
Thanks.


@page
@node Modules
@chapter Modules
@cindex modules

A module is a structure used to encapsulate related data and functions
with a restricted view from the outside.  Typically, modules are used
to hide implementation details through a well-defined set of functions
called the interface. 

Unlike classes or lambda functions modules are not part of the scheme
programming language.  Instead they live in a repository of the host
operating system---this repository is typically a hierarchical file
system.  A module is said to be @emph{open} when the module's code has been
loaded and evaluated in one of guile's environments.

From guile's point of view a module consists of two parts:
@cindex A set of expressions binding symbols to values in a given
        name space (See also the description about environments to learn
        about name spaces @ref{Environments}).
@cindex a configuration language for specifying the module's interface.

From the user's point of view the module system provides:
@cindex separate compilation
@cindex dynamic linking of compiled modules
@cindex use modules written in other languages
@cindex accessing and grouping name spaces

Note that modules do not provide encapsulation.  Instead the module
uses environments @ref{Environments} to provide name spaces and
encapsulation.

@menu
* Modules are not classes::
* Scheme and modules::          
* The Guile module system::     
@end menu


@node Modules are not classes
@section Modules are not classes

Since both classes and modules are data structures that divide 
a system into units it is easy to confuse both concepts.  But still
classes and modules are two orthogonal concepts:
@cindex A module is a structure that divides your software into @emph{physical}
units while
@index a class divides your software into @emph{logical} units.
Because modules structure the software system physicaly they can't be
part of the system they structure.  

Inside of the software system you can see reflections of the module
system like the differend environments that were created or the module
configuration language.  You can find lambda functions, arrays, vectors
and other kinds of objects here but you have to step out of the system
to identify the modules that structure your system.

Note also that classes and modules use differend techniques to access
exported features.  When a class inherits features from two different
classes and accidently two features have the same name, it will rename
one of them.  Because it would be a hard job to rename all features from
module A-rev1.1 just to access a feature of the older module A-rev1.0
the module system uses selective import instead of renaming.

@menu

@node Scheme and modules
@section Scheme and modules

Scheme, as defined in R4RS, does @emph{not} have a module system at all.

Aubrey Jaffer, mostly to support his portable Scheme library SLIB,
implemented a provide/require mechanism for many Scheme implementations.
Library files in SLIB @emph{provide} a feature, and when user programs
@emph{require} that feature, the library file is loaded in.

For example, the file @file{random.scm} in the SLIB package contains the
line
@smalllisp
(provide 'random)
@end smalllisp
so to use its procedures, a user would type
@smalllisp
(require 'random)
@end smalllisp
and they would magically become available, @emph{but still have the same
names!}  So this method is nice, but not as good as a full-featured
module system.

@node The Guile module system
@section The Guile module system

The current module system uses environments to separate name spaces.

@deffn the-environment
Returns a reference to the current name space.
@end deffn


@deffn ge environment
Go to or start a new repl in the name space `environment'.
@end deffn

@deffn module-environment
The name space in which all modules "live".
@end deffn

The module-environment's name spaces reflect the the structure that
modules provide.  Since every module is part of a larger package and
this package may be part of another package, a hierarchical name space is
used.  For example the module @code{ice-9 guile} can be found under
the name "ice-9/guile" and is part of the package ice-9 distributed
under the name "ice-9".  When the host operating system supports a
hierarchical file system this module can be found in under
$GUILE_LOAD_PATH/ice-9/guile.scm.

A module may or may not be open.  Opening a module means to create a new
environment for that module and then evaluate its code in this new
environment. Opened modules "live" in the module-environment.  

You must open a module to access the bindings it exports. On the other
hand it is not possible to compile a module that has been opened.

@deffn syntax define-module module-specification
@var{module-specification} is of the form @code{(hierarchy file)}.  One
example of this is
@smalllisp
(use-modules (ice-9 slib))
@end smalllisp
define-module makes this module available to Guile programs under the
given @var{module-specification}.
@end deffn


@deffn syntax define-public @dots{}
Makes a procedure or variable available to programs that use the current
module.
@end deffn

@deffn syntax use-modules module-specification
@var{module-specification} is of the form @code{(hierarchy file)}.  One
example of this is
@smalllisp
(use-modules (ice-9 slib))
@end smalllisp
use-modules allows the current Guile program to use all publicly defined
procedures and variables in the module denoted by
@var{module-specification}.
@end deffn

@deffn syntax open module-name
@var{module-name} is of the form @code{(package-1 package-2 package-n ... file)}.  One
example of this is
@smalllisp
(open (ice-9 slib))
@end smalllisp
This opens the module "ice-9/slib and appends i at the end of the
current module's useslist so that all bindings exported from "ice-9/slib"
are visible within the current module.
@end deffn

@deffn import module-name
@var{module-name} is of the form @code{(package-1 package-2 package-n ... file)}.  One
example of this is
@smalllisp
(go (create (my test)))
(import (ice-9 root))
(define exit exit)
(import )
(exit)
@end smalllisp
Same as open but starts a new import list.  
@end deffn

@deffn access module-name
Example:
@smalllisp
(define root-module (access (ice-9 root)))
@end smalllisp
@var{module-name} is of the form @code{(package-1 package-2 package-n ... file)}.  One
example of this is
@smalllisp
(define root (access (ice-9 root)))
@end smalllisp
Opens a module and returns a handle to the opened module.
@end deffn

@deffn ref module-handle name
Example:
@smalllisp
(ref root define)
@end smalllisp
Returns the value of `name'.  Looked up in the name space that belongs
to the module `module-handle'.
@end deffn

@deffn create module-name
@var{module-name} is of the form @code{(package-1 package-2 package-n ... file)}.  One
example of this is
@smalllisp
(define my-slib (create (my slib)))
@end smalllisp
Creates a new module and returns a handle to it.
@end deffn

@deffn go module-handle
example of this is
@smalllisp
(go my-slib)
@end smalllisp
Go to the environment that belongs to the module "ice-9/slib".
@end deffn

@deffn export list
example of this is
@smalllisp
(define a 1)
(define (b) (display a))
(define x)
(export a b)
@end smalllisp
Make features visible to all other modules.
@end deffn

@deffn protect list
example of this is
@smalllisp
(define version 1)
(protect version)
@end smalllisp
Make features visible to all members of the current package.
@end deffn


Some modules are included in the Guile distribution; here are references
to the entries in this manual which describe them in more detail:
@table @strong
@item (ice-9 guile)
The default repl
@item (ice-9 modules)
The module configuration language.  If you choose not to load this
module, you have to either manipulate the environments by hand or
write your own module configuration language.
@item (ice-9 debug)
Mikael Djurfeldt's source-level debugging support for Guile
(@pxref{debugger user interface}).
@item (ice-9 threads)
Guile's support for multi threaded execution (@pxref{Threads and Dynamic
Roots}).
@end table


@page
@node Module Internals
@chapter Module Internals

@menu
* Environments
* C code modules
* Dynamic Libraries::		Loading libraries of compiled code at run time.
@end menu

@node Environments
@section Environments

@node C code modules
@section C code modules

The module system also supports modules created by the guile snarfer.  
The @code{scm_c_module_registry} is an environment where all C modules
"live".  For example 
scm_make_subr("ice-9/regex-posix", scm_tc7_subr_1, scm_init_regex_posix, 
               scm_c_module_registry);

Registers the funtion @code{scm_init_regex_posix} that, once called
creates new bindings in the environment you pass it:
SCM scm_init_regex_posix (SCM env)
{
  scm_environment_intern (env, "basic", scm_long2num (REG_BASIC));
  ...
  return SCM_UNSPECIFIED;
}

Now create a scheme module called "ice-9/regex":
@smalllisp
((environment-ref (c-module-registry) 'ice-9/regex-posix) (the-environment))
(export basic)
@end smalllisp

@section Dynamic Linking and Compiled Code Modules

An example will hopefully make everything clear.  Suppose we want to
make the Bessel functions of the C library available to Scheme in the
module @samp{(math bessel)}.  First we need to write the appropriate
glue code to convert the arguments and return values of the functions
from Scheme to C and back.  Additionally, we need a function that will
@section Dynamic Linking and Compiled Code Modules
add them to the set of Guile primitives.  Because this is just an
example, we will only implement this for the @code{j0} function, tho.

@smallexample
#include <math.h>
#include <guile/gh.h>

SCM
j0_wrapper (SCM x)
@{
  return gh_double2scm (j0 (gh_scm2double (x)));
@}

SCM
init_math_bessel (SCM env)
@{
  gh_new_procedure1_0 ("j0", j0_wrapper, env);
@}
@end smallexample

We can already try to bring this into action by manually calling the low
level functions for performing dynamic linking.  The C source file needs
to be compiled into a shared library.  Here is how to do it on
GNU/Linux, please refer to the @code{libtool} documentation for how to
create dynamically linkable libraries portably.

@smallexample
gcc -shared -o libbessel.so -fPIC bessel.c
@end smallexample


Now create a module "my/math":

@smalllisp
(go (create (my math)))
(define bessel-lib (dynamic-link "./libbessel.so"))
(dynamic-call "init_math_bessel" bessel-lib (the-environment))
(export j)
@end smalllisp

The filename @file{./libbessel.so} should be pointing to the shared
library produced with the @code{gcc} command above, of course.  The
second line of the Guile interaction will call the
@code{init_math_bessel} function which in turn will register the C
function @code{j0_wrapper} with the Guile interpreter under the name
@code{j0}.  This function is available in module "my/math" and can
be accessed by:

@smalllisp
(go (create (my test)
(open (my math))
(j 0)
@result{} 0.223890779141236
@end smalllisp


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]