mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +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:
parent
a232c19ea5
commit
2b0ce070a3
1 changed files with 172 additions and 93 deletions
|
@ -3,9 +3,6 @@
|
|||
@chapter 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
|
||||
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}
|
||||
|
@ -73,60 +70,59 @@ module system.
|
|||
@node The Guile module system
|
||||
@section The Guile module system
|
||||
|
||||
In 1996 Tom Lord implemented a full-featured module system for Guile
|
||||
which allows loading Scheme source files into a private name space.
|
||||
In 1996 Tom Lord implemented a full-featured module system for Guile which
|
||||
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
|
||||
probably change to something more like the ML module system, so for now
|
||||
I will simply describe how it works for a couple of simple cases.
|
||||
For Guile version 1.5.0 and later, the system has been improved to have better
|
||||
integration from C code, more fine-grained user control over interfaces, and
|
||||
documentation.
|
||||
|
||||
So for example, the pipe interprocess communication interface
|
||||
(REFFIXME), contained in @file{$srcdir/ice-9/popen.scm}, starts out with
|
||||
|
||||
@smalllisp
|
||||
(define-module (ice-9 popen))
|
||||
@end smalllisp
|
||||
|
||||
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.
|
||||
Although it is anticipated that the module system implementation will
|
||||
change in the future, the Scheme programming interface described in this
|
||||
manual should be considered stable. The C programming interface is
|
||||
considered relatively stable, although at the time of this writing,
|
||||
there is still some flux.
|
||||
@c fixme: Review: Need better C code interface commentary.
|
||||
|
||||
@menu
|
||||
* 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.
|
||||
* More Module Procedures:: Low-level module code.
|
||||
* Module System Quirks:: Strange things to be aware of.
|
||||
* Included Guile Modules:: Which modules come with Guile?
|
||||
@end menu
|
||||
|
||||
@node General Information about Modules
|
||||
@subsection General Information about Modules
|
||||
|
||||
A Guile module is a collection of procedures, variables and syntactic
|
||||
forms (macros), which are either public or private. Public bindings are
|
||||
in the so-called @dfn{export list} of a module and can be made visible
|
||||
to other modules, which import them. This @dfn{module import} is called
|
||||
@dfn{using} of a module, and consists of loading of the module code (if
|
||||
it has not already been loaded) and making all exported items of the
|
||||
loaded module visible to the importing module (@pxref{Loading Guile
|
||||
A Guile module is a collection of named procedures, variables and
|
||||
macros, altogether called the @dfn{bindings}, since they bind, or
|
||||
associate, a symbol (the name) to a Scheme object (procedure, variable,
|
||||
or macro). Within a module, all bindings are visible. Certain bindings
|
||||
can be declared @dfn{public}, in which case they are added to the
|
||||
module's so-called @dfn{export list}; this set of public bindings is
|
||||
called the module's @dfn{public interface} (@pxref{Creating Guile
|
||||
Modules}).
|
||||
|
||||
The other side is called @dfn{defining} a module, and consists of giving
|
||||
a name to a module, add procedures and variables to it and declare which
|
||||
of the names should be exported when another module uses it
|
||||
(@pxref{Creating Guile Modules}).
|
||||
A client module @dfn{uses} a providing module's bindings by either
|
||||
accessing the providing module's public interface, or by building a
|
||||
custom interface (and then accessing that). In a custom interface, the
|
||||
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
|
||||
symbols. Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}.
|
||||
When Guile searches for the code of a module, it constructs the name of
|
||||
the file to load by concatenating the name elements with slashes between
|
||||
the elements and appending a number of file name extensions from the
|
||||
list @code{%load-extensions} (REFFIXME). The resulting file name is
|
||||
then searched in all directories in the variable @code{%load-path}. For
|
||||
To use a module, it must be found and loaded. All Guile modules have a
|
||||
unique @dfn{module name}, which is a list of one or more symbols.
|
||||
Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}. When Guile
|
||||
searches for the code of a module, it constructs the name of the file to
|
||||
load by concatenating the name elements with slashes between the
|
||||
elements and appending a number of file name extensions from the list
|
||||
@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
|
||||
@code{ice-9/popen.scm} and searched in the installation directory of
|
||||
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}).
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
you should keep in mind (@pxref{Module System Quirks}). We hope to
|
||||
address these eventually.
|
||||
|
||||
|
||||
@node Loading Guile Modules
|
||||
@subsection Loading Guile Modules
|
||||
@node Using 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
|
||||
all of the procedures available for Guile are immedietely available when
|
||||
you start up the interpreter. Some of the procedures are packaged in
|
||||
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
|
||||
An @dfn{interface specification} has one of two forms. The first
|
||||
variation is simply to name the module, in which case its public
|
||||
interface is the one accessed. For example:
|
||||
|
||||
@smalllisp
|
||||
(use-modules (ice-9 popen))
|
||||
@end smalllisp
|
||||
|
||||
@code{use-modules} allows the current Guile program to use all publicly
|
||||
defined procedures and variables in the modules denoted by the
|
||||
@var{module-specification}s.
|
||||
Here, the interface specification is @code{(ice-9 popen)}, and the
|
||||
result is that the current module now has access to @code{open-pipe},
|
||||
@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
|
||||
@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: Define term and concept `system transformer' somewhere.
|
||||
|
||||
@deffn syntax use-syntax module-specification
|
||||
Load the module @code{module-specification} and use its system
|
||||
@deffn syntax use-syntax module-name
|
||||
Load the module @code{module-name} and use its system
|
||||
transformer as the system transformer for the currently defined module,
|
||||
as well as installing it as the current system transformer.
|
||||
@end deffn
|
||||
|
@ -195,8 +244,6 @@ as well as installing it as the current system transformer.
|
|||
@node 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
|
||||
steps:
|
||||
|
||||
|
@ -209,13 +256,13 @@ to export, or which are required by the exported procedures.
|
|||
Add a @code{define-module} form at the beginning.
|
||||
|
||||
@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).
|
||||
@end itemize
|
||||
|
||||
@c begin (scm-doc-string "boot-9.scm" "define-module")
|
||||
@deffn syntax define-module module-specification [options @dots{}]
|
||||
@var{module-specification} is of the form @code{(hierarchy file)}. One
|
||||
@deffn syntax define-module module-name [options @dots{}]
|
||||
@var{module-name} is of the form @code{(hierarchy file)}. One
|
||||
example of this is
|
||||
|
||||
@smalllisp
|
||||
|
@ -223,16 +270,18 @@ example of this is
|
|||
@end smalllisp
|
||||
|
||||
@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
|
||||
defined module. The recognized options and their meaning is shown in
|
||||
the following table.
|
||||
|
||||
@c fixme: Should we use "#:" or ":"?
|
||||
|
||||
@table @code
|
||||
@item #:use-module @var{module}
|
||||
Equivalent to a @code{(use-modules @var{module})}. Use the specified
|
||||
@var{module} when loading this module.
|
||||
@item #:use-module @var{interface-specification}
|
||||
Equivalent to a @code{(use-modules @var{interface-specification})}
|
||||
(@pxref{Using Guile Modules}).
|
||||
|
||||
@item #:use-syntax @var{module}
|
||||
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")
|
||||
@deffn syntax define-public @dots{}
|
||||
Makes a procedure or variable available to programs that use the current
|
||||
module.
|
||||
Equivalent to @code{(begin (define foo ...) (export foo))}.
|
||||
@end deffn
|
||||
@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
|
||||
@subsection More Module Procedures
|
||||
|
||||
|
@ -294,6 +337,42 @@ Return an eval closure for the module @var{module}.
|
|||
@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
|
||||
@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.
|
||||
|
||||
@menu
|
||||
* Low level dynamic linking::
|
||||
* Compiled Code Modules::
|
||||
* Dynamic Linking and Compiled Code Modules::
|
||||
* Low level dynamic linking::
|
||||
* Compiled Code Modules::
|
||||
* Dynamic Linking and Compiled Code Modules::
|
||||
@end menu
|
||||
|
||||
@node Low level dynamic linking
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue