guile-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile/guile-core/doc scheme-modules.texi


From: Thien-Thi Nguyen
Subject: guile/guile-core/doc scheme-modules.texi
Date: Sun, 13 May 2001 04:22:04 -0700

CVSROOT:        /cvs
Module name:    guile
Changes by:     Thien-Thi Nguyen <address@hidden>       01/05/13 04:22:02

Modified files:
        guile-core/doc : scheme-modules.texi 

Log message:
        (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.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/doc/scheme-modules.texi.diff?cvsroot=OldCVS&tr1=1.7&tr2=1.8&r1=text&r2=text

Patches:
Index: guile/guile-core/doc/scheme-modules.texi
diff -u guile/guile-core/doc/scheme-modules.texi:1.7 
guile/guile-core/doc/scheme-modules.texi:1.8
--- guile/guile-core/doc/scheme-modules.texi:1.7        Fri May  4 14:54:00 2001
+++ guile/guile-core/doc/scheme-modules.texi    Sun May 13 04:22:01 2001
@@ -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}
@@ -72,61 +69,60 @@
 
 @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.
-
-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.
-
-So for example, the pipe interprocess communication interface
-(REFFIXME), contained in @file{$srcdir/ice-9/popen.scm}, starts out with
-
address@hidden
-(define-module (ice-9 popen))
address@hidden smalllisp
-
-and a user program can use
-
address@hidden
-(use-modules (ice-9 popen))
address@hidden smalllisp
 
-to have access to all procedures and variables exported from the module.
+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.
address@hidden fixme: Actually, was it available before?  1.4 seems a bit 
late...
+
+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.
+
+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.
address@hidden 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
address@hidden 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}).
-
-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
+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}).
+
+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
address@hidden (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 @@
 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.
 
 
address@hidden Loading Guile Modules
address@hidden Loading Guile Modules
address@hidden Using Guile Modules
address@hidden Using Guile Modules
 
address@hidden 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).
+
+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:
+
address@hidden
+(use-modules (ice-9 popen))
address@hidden smalllisp
 
-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
address@hidden 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.
+Here, the interface specification is @code{(ice-9 popen)}, and the
+result is that the current module now has access to @code{open-pipe},
address@hidden, @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:
 
address@hidden
+(use-modules ((ice-9 popen)
+              :select ((open-pipe . pipe-open) close-pipe)
+              :rename (symbol-prefix-proc 'unixy:)))
address@hidden 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:
+
address@hidden Use `smallexample' since `table' is ugly.  --ttn
address@hidden
+(ice-9 popen) sees:             current module sees:
+open-pipe                       unixy:pipe-open
+close-pipe                      unixy:close-pipe
address@hidden smallexample
+
+This example also shows how to use the convenience procedure
address@hidden
+
address@hidden begin (scm-doc-string "boot-9.scm" "symbol-prefix-proc")
address@hidden procedure symbol-prefix-proc prefix-sym
+Return a procedure that prefixes its arg (a symbol) with
address@hidden
address@hidden Insert gratuitous C++ slam here.  --ttn
address@hidden deffn
+
 @c begin (scm-doc-string "boot-9.scm" "use-modules")
address@hidden syntax use-modules module-specification @dots{}
-All @var{module-specification}s are of the form @code{(hierarchy file)}.
-One example of this is
address@hidden 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.
+
address@hidden can be a list of symbols, in which case it names a module
+whose public interface is found and used.
 
address@hidden can also be of the form:
+
 @smalllisp
-(use-modules (ice-9 popen))
+ (MODULE-NAME [:select SELECTION] [:rename RENAMER])
 @end smalllisp
+
+in which case a custom interface is newly created and used.
address@hidden 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.
 
address@hidden allows the current Guile program to use all publicly
-defined procedures and variables in the modules denoted by the
address@hidden
+Signal error if module name is not resolvable.
 @end deffn
address@hidden end
+
 
 @c FIXME::martin: Is this correct, and is there more to say?
 @c FIXME::martin: Define term and concept `system transformer' somewhere.
 
address@hidden syntax use-syntax module-specification
-Load the module @code{module-specification} and use its system
address@hidden 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 @@
 @node Creating Guile Modules
 @subsection Creating Guile Modules
 
address@hidden FIXME::martin: Review me!
-
 When you want to create your own modules, you have to take the following
 steps:
 
@@ -209,13 +256,13 @@
 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")
address@hidden syntax define-module module-specification [options @dots{}]
address@hidden is of the form @code{(hierarchy file)}.  One
address@hidden syntax define-module module-name [options @dots{}]
address@hidden is of the form @code{(hierarchy file)}.  One
 example of this is
 
 @smalllisp
@@ -223,16 +270,18 @@
 @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.
 
address@hidden fixme: Should we use "#:" or ":"?
+
 @table @code
address@hidden #:use-module @var{module}
-Equivalent to a @code{(use-modules @var{module})}.  Use the specified
address@hidden when loading this module.
address@hidden #: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 @@
 
 @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 @@
 @end deffn
 
 
address@hidden Module System Quirks
address@hidden 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.
+
address@hidden @bullet
+
address@hidden
+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.
+
address@hidden
+From C, you need to construct a @code{module-export!} call using
address@hidden  This is cumbersome.
+
address@hidden
+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
address@hidden 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.)
+
address@hidden
+[Add other quirks here.]
+
address@hidden itemize
+
+
 @node Included Guile Modules
 @subsection Included Guile Modules
 
@@ -398,9 +477,9 @@
 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]