1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 04:40:29 +02:00

(Modules): Remove "babbling" fixme.

(The Guile module system): Rewrite intro.
(General Information about Modules): Rewrite some parts.
Move problems to "Module System Quirks".
(Using Guile Modules): Renamed from "Loading Guile Modules".
Rewrite most parts.
Remove reivewme comment.
(Creating Guile Modules): Review, touch up.
Remove "Tkintr" comment.
(Module System Quirks): New node/subsection.
This commit is contained in:
Thien-Thi Nguyen 2001-05-13 11:22:01 +00:00
parent a232c19ea5
commit 2b0ce070a3

View file

@ -3,9 +3,6 @@
@chapter Modules @chapter Modules
@cindex modules @cindex modules
[FIXME: somewhat babbling; should be reviewed by someone who understands
modules, once the new module system is in place]
When programs become large, naming conflicts can occur when a function When programs become large, naming conflicts can occur when a function
or global variable defined in one file has the same name as a function or global variable defined in one file has the same name as a function
or global variable in another file. Even just a @emph{similarity} or global variable in another file. Even just a @emph{similarity}
@ -73,60 +70,59 @@ module system.
@node The Guile module system @node The Guile module system
@section The Guile module system @section The Guile module system
In 1996 Tom Lord implemented a full-featured module system for Guile In 1996 Tom Lord implemented a full-featured module system for Guile which
which allows loading Scheme source files into a private name space. allows loading Scheme source files into a private name space. This system has
been in available since Guile version 1.4.
@c fixme: Actually, was it available before? 1.4 seems a bit late...
This module system is regarded as being rather idiosyncratic, and will For Guile version 1.5.0 and later, the system has been improved to have better
probably change to something more like the ML module system, so for now integration from C code, more fine-grained user control over interfaces, and
I will simply describe how it works for a couple of simple cases. documentation.
So for example, the pipe interprocess communication interface Although it is anticipated that the module system implementation will
(REFFIXME), contained in @file{$srcdir/ice-9/popen.scm}, starts out with change in the future, the Scheme programming interface described in this
manual should be considered stable. The C programming interface is
@smalllisp considered relatively stable, although at the time of this writing,
(define-module (ice-9 popen)) there is still some flux.
@end smalllisp @c fixme: Review: Need better C code interface commentary.
and a user program can use
@smalllisp
(use-modules (ice-9 popen))
@end smalllisp
to have access to all procedures and variables exported from the module.
@menu @menu
* General Information about Modules:: Guile module basics. * General Information about Modules:: Guile module basics.
* Loading Guile Modules:: How to use existing modules. * Using Guile Modules:: How to use existing modules.
* Creating Guile Modules:: How to package your code into modules. * Creating Guile Modules:: How to package your code into modules.
* More Module Procedures:: Low-level module code. * More Module Procedures:: Low-level module code.
* Module System Quirks:: Strange things to be aware of.
* Included Guile Modules:: Which modules come with Guile? * Included Guile Modules:: Which modules come with Guile?
@end menu @end menu
@node General Information about Modules @node General Information about Modules
@subsection General Information about Modules @subsection General Information about Modules
A Guile module is a collection of procedures, variables and syntactic A Guile module is a collection of named procedures, variables and
forms (macros), which are either public or private. Public bindings are macros, altogether called the @dfn{bindings}, since they bind, or
in the so-called @dfn{export list} of a module and can be made visible associate, a symbol (the name) to a Scheme object (procedure, variable,
to other modules, which import them. This @dfn{module import} is called or macro). Within a module, all bindings are visible. Certain bindings
@dfn{using} of a module, and consists of loading of the module code (if can be declared @dfn{public}, in which case they are added to the
it has not already been loaded) and making all exported items of the module's so-called @dfn{export list}; this set of public bindings is
loaded module visible to the importing module (@pxref{Loading Guile called the module's @dfn{public interface} (@pxref{Creating Guile
Modules}). Modules}).
The other side is called @dfn{defining} a module, and consists of giving A client module @dfn{uses} a providing module's bindings by either
a name to a module, add procedures and variables to it and declare which accessing the providing module's public interface, or by building a
of the names should be exported when another module uses it custom interface (and then accessing that). In a custom interface, the
(@pxref{Creating Guile Modules}). client module can @dfn{select} which bindings to access and can also
algorithmically @dfn{rename} bindings. In contrast, when using the
providing module's public interface, the entire export list is available
without renaming (@pxref{Using Guile Modules}).
All Guile modules have unique names, which are lists of one or more To use a module, it must be found and loaded. All Guile modules have a
symbols. Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}. unique @dfn{module name}, which is a list of one or more symbols.
When Guile searches for the code of a module, it constructs the name of Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}. When Guile
the file to load by concatenating the name elements with slashes between searches for the code of a module, it constructs the name of the file to
the elements and appending a number of file name extensions from the load by concatenating the name elements with slashes between the
list @code{%load-extensions} (REFFIXME). The resulting file name is elements and appending a number of file name extensions from the list
then searched in all directories in the variable @code{%load-path}. For @code{%load-extensions} (REFFIXME). The resulting file name is then
searched in all directories in the variable @code{%load-path}. For
example, the @code{(ice-9 popen)} module would result in the filename example, the @code{(ice-9 popen)} module would result in the filename
@code{ice-9/popen.scm} and searched in the installation directory of @code{ice-9/popen.scm} and searched in the installation directory of
Guile and in all other directories in the load path. Guile and in all other directories in the load path.
@ -140,53 +136,106 @@ you can manipulate the current syntax transformer using the
definition option (@pxref{Creating Guile Modules}). definition option (@pxref{Creating Guile Modules}).
Please note that there are some problems with the current module system Please note that there are some problems with the current module system
you should keep in mind. When importing a module which exports a macro you should keep in mind (@pxref{Module System Quirks}). We hope to
definition, the other module must export all bindings the macro address these eventually.
expansion uses, too, because the expanded code would otherwise not be
able to see these definitions and issue a ``variable unbound'' error, or
worse, would use another binding which might be present in the scope of
the expansion.
When two or more modules are imported, and they export bindings with the
same names, the last imported module wins, and the exported binding of
that last module will silently be used. This might lead to
hard-to-find errors because wrong procedures or variables are used.
@node Loading Guile Modules @node Using Guile Modules
@subsection Loading Guile Modules @subsection Using Guile Modules
@c FIXME::martin: Review me! To use a Guile module is to access either its public interface or a
custom interface (@pxref{General Information About Modules}). Both
types of access are handled by the syntactic form @code{use-modules},
which accepts one or more interface specifications and, upon evaluation,
arranges for those interfaces to be available to the current module.
This process may include locating and loading code for a given module if
that code has not yet been loaded (REFFIXME %load-path).
There are several modules included in the Guile distribution, and not An @dfn{interface specification} has one of two forms. The first
all of the procedures available for Guile are immedietely available when variation is simply to name the module, in which case its public
you start up the interpreter. Some of the procedures are packaged in interface is the one accessed. For example:
modules, so that they are only accessible after the user has explicitly
said that she wants to use them. In Guile, the syntactic form
@code{use-modules} is used for telling the interpreter that he should
locate the code for a given module, load it and make the exported
bindings of the module visible to the caller.
@c begin (scm-doc-string "boot-9.scm" "use-modules")
@deffn syntax use-modules module-specification @dots{}
All @var{module-specification}s are of the form @code{(hierarchy file)}.
One example of this is
@smalllisp @smalllisp
(use-modules (ice-9 popen)) (use-modules (ice-9 popen))
@end smalllisp @end smalllisp
@code{use-modules} allows the current Guile program to use all publicly Here, the interface specification is @code{(ice-9 popen)}, and the
defined procedures and variables in the modules denoted by the result is that the current module now has access to @code{open-pipe},
@var{module-specification}s. @code{close-pipe}, @code{open-input-pipe}, and so on (@pxref{Included
Guile Modules}).
Note in the previous example that if the current module had already
defined @code{open-pipe}, that definition would be overwritten by the
definition in @code{(ice-9 popen)}. For this reason (and others), there
is a second variation of interface specification that not only names a
module to be accessed, but also selects bindings from it and renames
them to suit the current module's needs. For example:
@smalllisp
(use-modules ((ice-9 popen)
:select ((open-pipe . pipe-open) close-pipe)
:rename (symbol-prefix-proc 'unixy:)))
@end smalllisp
Here, the interface specification is more complex than before, and the
result is that a custom interface with only two bindings is created and
subsequently accessed by the current module. The mapping of old to new
names is as follows:
@c Use `smallexample' since `table' is ugly. --ttn
@smallexample
(ice-9 popen) sees: current module sees:
open-pipe unixy:pipe-open
close-pipe unixy:close-pipe
@end smallexample
This example also shows how to use the convenience procedure
@code{symbol-prefix-proc}.
@c begin (scm-doc-string "boot-9.scm" "symbol-prefix-proc")
@deffn procedure symbol-prefix-proc prefix-sym
Return a procedure that prefixes its arg (a symbol) with
@var{prefix-sym}.
@c Insert gratuitous C++ slam here. --ttn
@end deffn @end deffn
@c end
@c begin (scm-doc-string "boot-9.scm" "use-modules")
@deffn syntax use-modules spec @dots{}
Resolve each interface specification @var{spec} into an interface and
arrange for these to be accessible by the current module. The return
value is unspecified.
@var{spec} can be a list of symbols, in which case it names a module
whose public interface is found and used.
@var{spec} can also be of the form:
@smalllisp
(MODULE-NAME [:select SELECTION] [:rename RENAMER])
@end smalllisp
in which case a custom interface is newly created and used.
@var{module-name} is a list of symbols, as above; @var{selection} is a
list of selection-specs; and @var{renamer} is a procedure that takes a
symbol and returns its new name. A selection-spec is either a symbol or
a pair of symbols @code{(ORIG . SEEN)}, where @var{orig} is the name in
the used module and @var{seen} is the name in the using module. Note
that @var{seen} is also passed through @var{renamer}.
The @code{:select} and @code{:rename} clauses are optional. If both are
omitted, the returned interface has no bindings. If the @code{:select}
clause is omitted, @var{renamer} operates on the used module's public
interface.
Signal error if module name is not resolvable.
@end deffn
@c FIXME::martin: Is this correct, and is there more to say? @c FIXME::martin: Is this correct, and is there more to say?
@c FIXME::martin: Define term and concept `system transformer' somewhere. @c FIXME::martin: Define term and concept `system transformer' somewhere.
@deffn syntax use-syntax module-specification @deffn syntax use-syntax module-name
Load the module @code{module-specification} and use its system Load the module @code{module-name} and use its system
transformer as the system transformer for the currently defined module, transformer as the system transformer for the currently defined module,
as well as installing it as the current system transformer. as well as installing it as the current system transformer.
@end deffn @end deffn
@ -195,8 +244,6 @@ as well as installing it as the current system transformer.
@node Creating Guile Modules @node Creating Guile Modules
@subsection Creating Guile Modules @subsection Creating Guile Modules
@c FIXME::martin: Review me!
When you want to create your own modules, you have to take the following When you want to create your own modules, you have to take the following
steps: steps:
@ -209,13 +256,13 @@ to export, or which are required by the exported procedures.
Add a @code{define-module} form at the beginning. Add a @code{define-module} form at the beginning.
@item @item
Export all bindings which should be visible to importing modules, either Export all bindings which should be in the public interface, either
by using @code{define-public} or @code{export} (both documented below). by using @code{define-public} or @code{export} (both documented below).
@end itemize @end itemize
@c begin (scm-doc-string "boot-9.scm" "define-module") @c begin (scm-doc-string "boot-9.scm" "define-module")
@deffn syntax define-module module-specification [options @dots{}] @deffn syntax define-module module-name [options @dots{}]
@var{module-specification} is of the form @code{(hierarchy file)}. One @var{module-name} is of the form @code{(hierarchy file)}. One
example of this is example of this is
@smalllisp @smalllisp
@ -223,16 +270,18 @@ example of this is
@end smalllisp @end smalllisp
@code{define-module} makes this module available to Guile programs under @code{define-module} makes this module available to Guile programs under
the given @var{module-specification}. the given @var{module-name}.
The @var{options} are keyword/value pairs which specify more about the The @var{options} are keyword/value pairs which specify more about the
defined module. The recognized options and their meaning is shown in defined module. The recognized options and their meaning is shown in
the following table. the following table.
@c fixme: Should we use "#:" or ":"?
@table @code @table @code
@item #:use-module @var{module} @item #:use-module @var{interface-specification}
Equivalent to a @code{(use-modules @var{module})}. Use the specified Equivalent to a @code{(use-modules @var{interface-specification})}
@var{module} when loading this module. (@pxref{Using Guile Modules}).
@item #:use-syntax @var{module} @item #:use-syntax @var{module}
Use @var{module} when loading the currently defined module, and install Use @var{module} when loading the currently defined module, and install
@ -266,17 +315,11 @@ bindings of the current module.
@c begin (scm-doc-string "boot-9.scm" "define-public") @c begin (scm-doc-string "boot-9.scm" "define-public")
@deffn syntax define-public @dots{} @deffn syntax define-public @dots{}
Makes a procedure or variable available to programs that use the current Equivalent to @code{(begin (define foo ...) (export foo))}.
module.
@end deffn @end deffn
@c end @c end
[FIXME: must say more, and explain, and also demonstrate a private name
space use, and demonstrate how one would do Python's "from Tkinter
import *" versus "import Tkinter". Must also add something about paths
and standards for contributed modules.]
@node More Module Procedures @node More Module Procedures
@subsection More Module Procedures @subsection More Module Procedures
@ -294,6 +337,42 @@ Return an eval closure for the module @var{module}.
@end deffn @end deffn
@node Module System Quirks
@subsection Module System Quirks
Although the programming interfaces are relatively stable, the Guile
module system itself is still evolving. Here are some situations where
usage surpasses design.
@itemize @bullet
@item
When using a module which exports a macro definition, the other module
must export all bindings the macro expansion uses, too, because the
expanded code would otherwise not be able to see these definitions and
issue a ``variable unbound'' error, or worse, would use another binding
which might be present in the scope of the expansion.
@item
From C, you need to construct a @code{module-export!} call using
@code{gh_eval_str}. This is cumbersome.
@item
When two or more used modules export bindings with the same names, the
last accessed module wins, and the exported binding of that last module
will silently be used. This might lead to hard-to-find errors because
wrong procedures or variables are used. To avoid this kind of
@dfn{name-clash} situation, use a custom interface specification
(@pxref{Using Guile Modules}). (We include this entry for the possible
benefit of users of Guile versions previous to 1.5.0, when custom
interfaces were added to the module system.)
@item
[Add other quirks here.]
@end itemize
@node Included Guile Modules @node Included Guile Modules
@subsection Included Guile Modules @subsection Included Guile Modules
@ -398,9 +477,9 @@ dynamic linking apparatus, and a more high-level interface that
integrates dynamically linked libraries into the module system. integrates dynamically linked libraries into the module system.
@menu @menu
* Low level dynamic linking:: * Low level dynamic linking::
* Compiled Code Modules:: * Compiled Code Modules::
* Dynamic Linking and Compiled Code Modules:: * Dynamic Linking and Compiled Code Modules::
@end menu @end menu
@node Low level dynamic linking @node Low level dynamic linking