mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +02:00
* modules/module-snippets.texi: New file, documenting the module
system. Placed in `devel' for review purposes.
This commit is contained in:
parent
438201b47f
commit
a080fe396c
2 changed files with 739 additions and 0 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2001-05-07 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||||
|
|
||||||
|
* modules/module-snippets.texi: New file, documenting the module
|
||||||
|
system. Placed in `devel' for review purposes.
|
||||||
|
|
||||||
2001-03-16 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
2001-03-16 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||||
|
|
||||||
* modules: New directory.
|
* modules: New directory.
|
||||||
|
|
734
devel/modules/module-snippets.texi
Normal file
734
devel/modules/module-snippets.texi
Normal file
|
@ -0,0 +1,734 @@
|
||||||
|
\input texinfo
|
||||||
|
@c -*-texinfo-*-
|
||||||
|
@c %**start of header
|
||||||
|
@setfilename module-snippets.info
|
||||||
|
@settitle Module Snippets
|
||||||
|
@iftex
|
||||||
|
@afourpaper
|
||||||
|
@end iftex
|
||||||
|
@c %**end of header
|
||||||
|
|
||||||
|
@set UPDATED 7May 2001
|
||||||
|
@set EDITION 0.0.1
|
||||||
|
@set VERSION 0.0.1
|
||||||
|
|
||||||
|
@dircategory Guile
|
||||||
|
@direntry
|
||||||
|
* module-snippets: (module-snippets). Documentation for the Guile Module System
|
||||||
|
@end direntry
|
||||||
|
|
||||||
|
|
||||||
|
@c --- title page starts here ---
|
||||||
|
|
||||||
|
@titlepage
|
||||||
|
@title Module Snippets
|
||||||
|
@subtitle Documentation for the Guile Module System
|
||||||
|
@subtitle Version @value{VERSION}
|
||||||
|
@author Martin Grabmueller
|
||||||
|
|
||||||
|
@c The following two commands
|
||||||
|
@c start the copyright page.
|
||||||
|
@page
|
||||||
|
@vskip 0pt plus 1filll
|
||||||
|
Copyright @copyright{} 2001 Martin Grabmueller
|
||||||
|
|
||||||
|
Permission is granted to make and distribute verbatim copies of
|
||||||
|
this manual provided the copyright notice and this permission notice
|
||||||
|
are preserved on all copies.
|
||||||
|
@end titlepage
|
||||||
|
|
||||||
|
@c --- title page ends here ---
|
||||||
|
|
||||||
|
@syncodeindex vr cp
|
||||||
|
@syncodeindex fn cp
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Top, Introduction, (dir), (dir)
|
||||||
|
|
||||||
|
@ifinfo
|
||||||
|
This file tries to shed some light on Guile's current module system.
|
||||||
|
@end ifinfo
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Introduction:: What is this all about?
|
||||||
|
* Module Data Type:: Modules from a data-centric view.
|
||||||
|
* Modules and Evaluation:: Interaction between the module system
|
||||||
|
and the evaluator.
|
||||||
|
* Index:: Procedure index.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Introduction, Module Data Type, Top, Top
|
||||||
|
@chapter Introduction
|
||||||
|
|
||||||
|
This document contains all information about the module system I have
|
||||||
|
been able to deduce from the source code or from mailing list
|
||||||
|
conversation. I have written down everything while trying to figure out
|
||||||
|
how the Guile module system actually works, and some of the text is
|
||||||
|
taken from commentary in the file @file{boot-9.scm}.
|
||||||
|
|
||||||
|
The information contained herein is surely not complete, and I will be
|
||||||
|
happy to receive additions, corrections and suggestions for improving
|
||||||
|
it.
|
||||||
|
|
||||||
|
Also note that the information contained in this document reflects the
|
||||||
|
current state as of the time writing, and the facts stated are not
|
||||||
|
guaranteed to be stable. A complete redesign of the module system is
|
||||||
|
planned for a long time now, and actually might happen some day.
|
||||||
|
|
||||||
|
There are basically three views on the module system:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Data-centric: The module as a data type, with all procedures for
|
||||||
|
creating and manipulating modules. This is documented in the
|
||||||
|
@ref{Module Data Type}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Declarational: How to use declarations like @code{use-modules} or
|
||||||
|
@code{define-module} for dealing with modules and the scoping mechanisms
|
||||||
|
they provide. This issue is documented in the Guile Reference Manual,
|
||||||
|
and will not be covered in detail here.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Internal: How do the module system and the Guile evaluator interact?
|
||||||
|
This is documented in @ref{Modules and Evaluation}.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Module Data Type, Modules and Evaluation, Introduction, Top
|
||||||
|
@chapter Module Data Type
|
||||||
|
|
||||||
|
This chapter will describe the module system from the point of the data
|
||||||
|
type @code{module}. Thus we will first see what this data type looks
|
||||||
|
like and what operations are defined on it.
|
||||||
|
|
||||||
|
Modules in Guile are instances of a data type @code{module}. A module
|
||||||
|
has the following fields.
|
||||||
|
|
||||||
|
@table @var
|
||||||
|
@item obarray
|
||||||
|
This is a hash table which contains all bindings made in the module.
|
||||||
|
|
||||||
|
@item uses-list
|
||||||
|
List of the modules imported by the module. A lot of search procedures
|
||||||
|
search through all modules in this list when a specified binding cannot
|
||||||
|
be found in the module's obarray.
|
||||||
|
|
||||||
|
@item lazy-binding-proc
|
||||||
|
A procedure for determining a binding for a module lazily. This is
|
||||||
|
invoked if a binding for a name is requested from the module, but does
|
||||||
|
not exist. The procedure can create a new binding, by loading
|
||||||
|
additional code or fetching it from another module/data structure.
|
||||||
|
|
||||||
|
@item eval-closure
|
||||||
|
A procedure for determining a binding in a module. The evaluator uses
|
||||||
|
this procedure for accessing top-level variables.
|
||||||
|
|
||||||
|
@item transformer
|
||||||
|
The syntax transformer used for all evaluations in the module.
|
||||||
|
|
||||||
|
@item name
|
||||||
|
The name of the module. This is a list of symbols, such as
|
||||||
|
@code{(guile)} or @code{(ice-9 popen)}.
|
||||||
|
|
||||||
|
@item kind
|
||||||
|
A symbol describing the type of the module. Normal modules are of type
|
||||||
|
@code{module}, interfaces are of type @code{interface} and directories
|
||||||
|
(modules which implement the hierarchical namespace) are of kind
|
||||||
|
@code{directory}). Autoload modules (placeholder for not-yet-loaded
|
||||||
|
modules) are of type @code{autoload}. FIXME: Are there other types?
|
||||||
|
|
||||||
|
@item observers
|
||||||
|
A list of procedures to call when one of the module's bindings is
|
||||||
|
removed or modified or a new binding is created.
|
||||||
|
|
||||||
|
@item weak-observers
|
||||||
|
Similar to @var{observers}, but this is a hash table from which the
|
||||||
|
observer procedures will magically disappear when there are no other
|
||||||
|
references to the procedure left except from the module they observe.
|
||||||
|
|
||||||
|
@item observer-id
|
||||||
|
This is an integer, which specifies the identifer the next weak observer
|
||||||
|
will get. It is incremented each time a weak observer is added.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* The Data Type:: The data type @code{module}.
|
||||||
|
* Module Loading:: How to load modules.
|
||||||
|
* Modules and Variables:: How do variables and modules relate.
|
||||||
|
* Iterating over Module Bindings:: How to access all bindings of a module.
|
||||||
|
* The Lazy Binder:: The lazy binding procedures.
|
||||||
|
* Module Observers:: The observer protocol.
|
||||||
|
* The Current Module:: Notion of ``current module'' in Guile.
|
||||||
|
* High-Level Module Access:: High-level access to module features.
|
||||||
|
* Recursive Namespaces:: Hierarchical organisation of namespaces.
|
||||||
|
* Module Hierarchy:: The currently implemented hierarchy.
|
||||||
|
* Modules and Interfaces:: How modules implement different scopes.
|
||||||
|
* Modules and Environments:: Relation between modules and environments.
|
||||||
|
* Modules Miscallenea:: Miscellaneous module procedures.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node The Data Type, Module Loading, Module Data Type, Module Data Type
|
||||||
|
@section The Data Type
|
||||||
|
|
||||||
|
A new module is created using @code{make-module}. Several procedures
|
||||||
|
are defined for accessing the members of a module.
|
||||||
|
|
||||||
|
@deffn procedure make-module size uses-list lazy-binding-proc
|
||||||
|
Create a new module and initialize its fields with the parameters.
|
||||||
|
|
||||||
|
@table @var
|
||||||
|
@item size
|
||||||
|
Size of the module's obarray.
|
||||||
|
|
||||||
|
@item uses-list
|
||||||
|
List of the modules imported by the module.
|
||||||
|
|
||||||
|
@item lazy-binding-proc
|
||||||
|
The procedure for determining a binding for a module lazily.
|
||||||
|
@end table
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
The various fields of a module can be accessed and modified using the
|
||||||
|
following procedures:
|
||||||
|
|
||||||
|
@deffn procedure module-obarray module
|
||||||
|
@deffnx procedure set-module-obarray! module obj
|
||||||
|
@deffnx procedure module-uses module
|
||||||
|
@deffnx procedure set-module-uses! module obj
|
||||||
|
@deffnx procedure module-binder module
|
||||||
|
@deffnx procedure set-module-binder! module obj
|
||||||
|
@deffnx procedure module-eval-closure module
|
||||||
|
@deffnx procedure set-module-eval-closure! module obj
|
||||||
|
@deffnx procedure module-transformer module
|
||||||
|
@deffnx procedure set-module-transformer! module obj
|
||||||
|
@deffnx procedure module-name module
|
||||||
|
@deffnx procedure set-module-name! module obj
|
||||||
|
@deffnx procedure module-kind module
|
||||||
|
@deffnx procedure set-module-kind! module obj
|
||||||
|
@deffnx procedure module-observers module
|
||||||
|
@deffnx procedure set-module-observers! module obj
|
||||||
|
@deffnx procedure module-weak-observers module
|
||||||
|
@deffnx procedure module-observer-id module
|
||||||
|
@deffnx procedure set-module-observer-id! module obj
|
||||||
|
Read the corresponding member of @var{module}, or write the value
|
||||||
|
@var{obj} into the slot.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module? obj
|
||||||
|
This is the type predicate for modules, which will return @code{#t} if
|
||||||
|
its argument is a module, and @code{#f} otherwise.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure make-scm-module
|
||||||
|
This will create a module which represents Guile's builtin bindings.
|
||||||
|
Initially, it is empty, but when variable lookups are made in it, the
|
||||||
|
requested bindings will get copied into the module from the internal
|
||||||
|
obarray. Bindings will get copied even if only accessed.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure make-root-module
|
||||||
|
Create a new module which works on the internal obarrary. The
|
||||||
|
difference to the modules returned by @code{make-scm-module} is that
|
||||||
|
bindings are only copied to the obarray if they are explicitly defined.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Module Loading, Modules and Variables, The Data Type, Module Data Type
|
||||||
|
@section Module Loading
|
||||||
|
|
||||||
|
The normal way of loading modules in Scheme programs is to use the
|
||||||
|
special form @code{use-modules}, which loads the source of one or more
|
||||||
|
specified modules and imports their public bindings into the current
|
||||||
|
module. This procedure is documented in the Guile Reference Manual, so
|
||||||
|
I will not go into details here. This section rather contains the
|
||||||
|
underlying mechanisms, on which @code{use-modules} is built.
|
||||||
|
|
||||||
|
Normally, you will not need to create new modules explicitly, adding
|
||||||
|
definitions to it manually. For more often, you will want to load some
|
||||||
|
Scheme code from a file, and install its definitions into a module, only
|
||||||
|
exporting the public bits. This is what the procedure
|
||||||
|
@code{resolve-module} is for.
|
||||||
|
|
||||||
|
@deffn procedure resolve-module name [maybe-autoload]
|
||||||
|
If the module @var{name} already exists, return it. Otherwise, try to
|
||||||
|
load the Scheme code for @var{name} into a newly created module, adding
|
||||||
|
the exports to the public interface.
|
||||||
|
|
||||||
|
The parameter @var{maybe-autoload} controls the behaviour when the
|
||||||
|
module code is going to be loaded.
|
||||||
|
|
||||||
|
@table @asis
|
||||||
|
@item @var{maybe-autoload} == @code{#f}
|
||||||
|
Do not defer loading.
|
||||||
|
|
||||||
|
@item @var{maybe-autoload} == @code{#t}
|
||||||
|
Defer loading of the source code until a binding from the module is
|
||||||
|
requested.
|
||||||
|
|
||||||
|
@item @var{maybe-autoload} not given
|
||||||
|
Like @var{maybe-autoload} == @code{#t}.
|
||||||
|
@end table
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Modules and Variables, Iterating over Module Bindings, Module Loading, Module Data Type
|
||||||
|
@section Modules and Variables
|
||||||
|
|
||||||
|
Modules can be regarded as mappings from symbols (variable names) to
|
||||||
|
bindings (variable locations). The procedures documented in this
|
||||||
|
section can be used to test whether such a mapping exists for a given
|
||||||
|
variable name, how to add mappings and how to retrieve a variables
|
||||||
|
value.
|
||||||
|
|
||||||
|
We sometimes want to look for properties of a symbol just within the
|
||||||
|
obarray of one module. If the property holds, then it is said to hold
|
||||||
|
``locally'' as in, ``The symbol @code{display} is locally rebound in the
|
||||||
|
module @code{safe-guile}.''
|
||||||
|
|
||||||
|
Other times, we want to test for a symbol property in the obarray of
|
||||||
|
@var{m} and, if it is not found there, try each of the modules in the
|
||||||
|
uses list of @var{m}. This is the normal way of testing for some
|
||||||
|
property, so we state these properties without qualification as in:
|
||||||
|
``The symbol 'fnord is interned in module M because it is interned
|
||||||
|
locally in module @var{m2} which is a member of the uses list of
|
||||||
|
@var{m}.''
|
||||||
|
|
||||||
|
@deffn procedure module-locally-bound? module sym
|
||||||
|
Test if @var{sym} is bound in @var{module} directly, e.g. it does not
|
||||||
|
suffice that @var{sym} is bound in one of the used modules of
|
||||||
|
@var{module}. @dfn{Bound} means that the symbol is interned and bound
|
||||||
|
to some well-defined value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-bound? module sym
|
||||||
|
Return true if @var{sym} is bound in @var{module} or one of the modules
|
||||||
|
in @var{module}'s uses list. The search looks in all transitively used
|
||||||
|
modules. @dfn{Bound} means that the symbol is interned and bound to
|
||||||
|
some well-defined value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-symbol-locally-interned? module sym
|
||||||
|
Test if @var{sym} is interned in @var{module} directly, e.g. it does not
|
||||||
|
suffice that @var{sym} is bound in one of the used modules of
|
||||||
|
@var{module}. Unlike @code{module-locally-bound}, the symbol is not
|
||||||
|
required to be bound to a well-defined value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-symbol-interned? module sym
|
||||||
|
Return true if @var{sym} is interned in @var{module} or one of the
|
||||||
|
modules in @var{module}'s uses list. The search looks in all
|
||||||
|
transitively used modules. Unlike @code{module-bound}, the symbol is
|
||||||
|
not required to be bound to a well-defined value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-local-variable module sym
|
||||||
|
Return a variable object for @var{SYM} in the module @var{module}, or
|
||||||
|
@code{#f} if no such symbol is defined in @var{module}. If the symbols
|
||||||
|
is not found at first, but the module has a lazy binder, then try the
|
||||||
|
binder.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-variable module sym
|
||||||
|
Return a variable object for @var{sym} in the module @var{module} or one
|
||||||
|
of its used modules, or @code{#f} if no such symbol is defined in
|
||||||
|
@var{module} or its uses.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-symbol-local-binding module symbol [opt-value]
|
||||||
|
Return the value of the binding called @var{symbol} in @var{module}, or
|
||||||
|
@var{opt-val} if no such binding exists. If no @var{opt-value} is given
|
||||||
|
and no binding exists, an error is thrown.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-symbol-binding module symbol [opt-value]
|
||||||
|
Return the value of the binding called @var{symbol} in @var{module}, or
|
||||||
|
@var{opt-val} if no such binding exists. If no @var{opt-value} is given
|
||||||
|
and no binding exists, an error is thrown. Unlike
|
||||||
|
@code{module-symbol-local-binding}, this will search all used modules as
|
||||||
|
well as @var{module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-make-local-var! module symbol
|
||||||
|
Create a binding for a variable called @var{symbol} in @var{module} and
|
||||||
|
return the variable object representing the new location in the module.
|
||||||
|
If @var{symbol} is already defined in @var{module}, nothing happens.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-add! module symbol var
|
||||||
|
Add the variable @var{var} to @var{module} under the name @var{symbol}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-remove! module symbol
|
||||||
|
Remove the binding for @var{symbol} in @var{module}. The return value
|
||||||
|
is not specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-clear! module
|
||||||
|
Remove all bindings from @var{module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Iterating over Module Bindings, The Lazy Binder, Modules and Variables, Module Data Type
|
||||||
|
@section Iterating over Module Bindings
|
||||||
|
|
||||||
|
@deffn procedure module-for-each proc module
|
||||||
|
Apply @var{proc} to every binding in @var{module}. @var{proc} is called
|
||||||
|
with two parameters, the name and variable for each binding.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-map proc module
|
||||||
|
Apply @var{proc} to every binding in @var{module} and return a list of
|
||||||
|
the results of all applications of @var{proc}. @var{proc} is called
|
||||||
|
with two parameters, the name and variable for each binding.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node The Lazy Binder, Module Observers, Iterating over Module Bindings, Module Data Type
|
||||||
|
@section The Lazy Binder
|
||||||
|
|
||||||
|
The lazy binding procedures which are connected to modules are invoked
|
||||||
|
every time a binding is searched in a module, but is not present. A
|
||||||
|
binder is called with three arguments.
|
||||||
|
|
||||||
|
When a lazy binder returns a variable object, the search is successful
|
||||||
|
and the return value will be used. If the return value is @code{#f},
|
||||||
|
the search is continued in the modules from the uses list. FIXME: Is
|
||||||
|
this always the case or only in the standard eval closure?
|
||||||
|
|
||||||
|
@table @var
|
||||||
|
@item module
|
||||||
|
The module for which the binding is requested.
|
||||||
|
|
||||||
|
@item symbol
|
||||||
|
The name of the searched symbol.
|
||||||
|
|
||||||
|
@item define?
|
||||||
|
@code{#t} if the binding should be defined, @code{#f} otherwise.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Module Observers, The Current Module, The Lazy Binder, Module Data Type
|
||||||
|
@section Module Observers
|
||||||
|
|
||||||
|
A module can have a number of @dfn{observers} attached. These are
|
||||||
|
procedures which are called whenever something withing the module
|
||||||
|
changes. This can be the creation, deletion or modification of a
|
||||||
|
binding.
|
||||||
|
|
||||||
|
When a change occurs, the procedure @code{module-modified} (documented
|
||||||
|
below in this section) will be called which in turn will apply all
|
||||||
|
observer procedures to the modified module.
|
||||||
|
|
||||||
|
@deffn procedure module-observe module proc
|
||||||
|
Add the observer @var{proc} to @var{module} and return a pair of
|
||||||
|
@var{module} and @var{proc}. The returned value can be used with
|
||||||
|
@code{module-unobserve}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-observe-weak module proc
|
||||||
|
Add @var{proc} as a weak observer to @var{module} and erturn a pair of
|
||||||
|
@var{module} and a unique integer, the observer ID. The returned value
|
||||||
|
can be used with @code{module-unobserve}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-unobserve token
|
||||||
|
Remove an observer from a module. The module and the observer to be
|
||||||
|
removed are taken from @var{token}, which must be returned by
|
||||||
|
@code{module-observe} or @code{module-unobserve}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-modified m
|
||||||
|
Signal a modification of module @var{m} to all associated observers.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node The Current Module, High-Level Module Access, Module Observers, Module Data Type
|
||||||
|
@section The Current Module
|
||||||
|
|
||||||
|
For all evaluations, Guile maintains a so-called @dfn{current
|
||||||
|
module}.@footnote{A current module does not exist until Guile has been
|
||||||
|
completely booted, that means until @file{boot-9.scm} has been loaded.
|
||||||
|
But this should be no issue unless you are doing weird things withe the
|
||||||
|
module system, which might be a bad idea, but YMMV.} This is used for
|
||||||
|
all top-level definitions and variable lookups. When the current module
|
||||||
|
changes, new definitions will go to the new module. The procedures in
|
||||||
|
this section manipulate the notion of the current module.
|
||||||
|
|
||||||
|
The current module is also used when C code calls @code{scm_make_gsubr}
|
||||||
|
for creating new primitives or @code{scm_sysintern} for interning
|
||||||
|
symbols. From C, the current module can be set by calling
|
||||||
|
@code{scm_set_current_module}, which will return the old module. This
|
||||||
|
returned module can later be used to switch back to the old module after
|
||||||
|
creating a new one and installing bindings there.
|
||||||
|
|
||||||
|
|
||||||
|
@deffn procedure set-current-module module
|
||||||
|
Make @var{module} the current module, into which all following
|
||||||
|
definitions will go. Return the old module in effect before the call to
|
||||||
|
@code{set-current-module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure current-module
|
||||||
|
Return the module which is currently registered as the @dfn{current
|
||||||
|
module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node High-Level Module Access, Recursive Namespaces, The Current Module, Module Data Type
|
||||||
|
@section High-Level Module Access
|
||||||
|
|
||||||
|
The procedure in the previous chapter are not for general use. The
|
||||||
|
current chapter will document all procedures which are meant to be used
|
||||||
|
by users who need to work with modules.
|
||||||
|
|
||||||
|
The parameter @var{module} in the following descriptions must be a
|
||||||
|
module, @var{name} must be a symbol (which most probably will need to be
|
||||||
|
quoted).
|
||||||
|
|
||||||
|
@deffn procedure module-ref module name [default]
|
||||||
|
Return the value of a variable called @var{name} in @var{module} or any
|
||||||
|
of its used modules. If there is no such variable, then if the optional
|
||||||
|
third argument @var{default} is present, it is returned; otherwise an
|
||||||
|
error is signaled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-set! module name value
|
||||||
|
Sets the variable called @var{name} in @var{module} (or in a module that
|
||||||
|
@var{module} uses) to @var{value}; if there is no such variable, an
|
||||||
|
error is signaled.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-define! module name value
|
||||||
|
Sets the variable called @var{name} in @var{module} to @var{value}; if
|
||||||
|
there is no such variable, it is added first.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-defined? module name
|
||||||
|
Return @code{#t} if @var{name} is defined in @var{module} (or in a
|
||||||
|
module that @var{module} uses).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-use! module interface
|
||||||
|
Add @var{interface} to the list of interfaces used by @var{module}. For
|
||||||
|
information what an @dfn{interface} is, see @ref{Modules and
|
||||||
|
Interfaces}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure module-export! module names
|
||||||
|
Add all variables from @var{names} (a list of symbols) to the public
|
||||||
|
interface of @var{module} (@pxref{Modules and Interfaces}).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Recursive Namespaces, Module Hierarchy, High-Level Module Access, Module Data Type
|
||||||
|
@section Recursive Namespaces
|
||||||
|
|
||||||
|
A hierarchical namespace emerges if we consider some module to be root,
|
||||||
|
and variables bound to modules as nested namespaces.
|
||||||
|
|
||||||
|
The modules which implement the internal nodes are of kind
|
||||||
|
@code{directory}. FIXME: Is this correct?
|
||||||
|
|
||||||
|
The routines in this chapter manage variable names in hierarchical
|
||||||
|
namespace. Each variable name is a list of elements, looked up in
|
||||||
|
successively nested modules.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(nested-ref some-root-module '(foo bar baz))
|
||||||
|
@result{}
|
||||||
|
<value of a variable named baz in the module bound to bar in
|
||||||
|
the module bound to foo in some-root-module>
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@deffn procedure nested-ref root names
|
||||||
|
Look up the variable identified by the symbol list @var{names}, starting
|
||||||
|
in the module @var{root}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure nested-set! root names val
|
||||||
|
Set the variable identified by the symbol list @var{names} to @var{val},
|
||||||
|
starting the variable lookup in module @var{root}. The return value is
|
||||||
|
not specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure nested-define! root names val
|
||||||
|
Set the variable identified by the symbol list @var{names} to @var{val},
|
||||||
|
starting the variable lookup in module @var{root}. If the variable does
|
||||||
|
not exist, create it before setting its value. The return value is not
|
||||||
|
specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure nested-remove! root names
|
||||||
|
Remove the variable identified by the symbol list @var{names}, starting
|
||||||
|
the variable lookup in module @var{root}. The return value is not
|
||||||
|
specified.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure local-ref names
|
||||||
|
@deffnx procedure local-set! names val
|
||||||
|
@deffnx procedure local-define! names val
|
||||||
|
@deffnx procedure local-remove! names
|
||||||
|
Like the @code{nested-ref}, @code{nested-set!}, @code{nested-define!}
|
||||||
|
and @code{nested-remove!} procedures above, but start the variable
|
||||||
|
lookup in the module returned by @code{current-module}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Module Hierarchy, Modules and Interfaces, Recursive Namespaces, Module Data Type
|
||||||
|
@section Module Hierarchy
|
||||||
|
|
||||||
|
Currently, the following entries are defined in the hierarchical
|
||||||
|
namespace.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item (app)
|
||||||
|
This is the root of all named objects which are not in the top level.
|
||||||
|
|
||||||
|
@item (app modules)
|
||||||
|
This is the directory of all modules.
|
||||||
|
|
||||||
|
@item (app modules guile)
|
||||||
|
This is the standard root module.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
User modules which are loaded into Guile as well as the modules shipped
|
||||||
|
with the Guile distribution are installed under @code{(app modules)} as
|
||||||
|
well.
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Modules and Interfaces, Modules and Environments, Module Hierarchy, Module Data Type
|
||||||
|
@section Modules and Interfaces
|
||||||
|
|
||||||
|
Interfaces are modules of kind @code{interface}. They always belong to
|
||||||
|
another module and contain the bindings which are exported from that
|
||||||
|
module. Interfaces are the means by which the different scopes of a
|
||||||
|
module (private vs. public bindings) are implemented.
|
||||||
|
|
||||||
|
Every module can define a special variable called
|
||||||
|
@code{%module-public-interface}, which is bound to the module's
|
||||||
|
interface.
|
||||||
|
|
||||||
|
Whenever a variable is exported (with the @code{export} form or the
|
||||||
|
@code{:export} keyword in the @code{define-module} form), this variable
|
||||||
|
is added to the defining module's interface. Because importing a module
|
||||||
|
means adding other modules' interfaces to the uses list, the exported
|
||||||
|
variables become visible in the importing module.
|
||||||
|
|
||||||
|
@deffn procedure module-public-interface m
|
||||||
|
Return the public interface of module @var{m}, or @code{#f} if @var{m}
|
||||||
|
does not have a public interface.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn procedure set-module-public-interface! m i
|
||||||
|
Set the public interface of the module @var{m} to @var{i}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Modules and Environments, Modules Miscallenea, Modules and Interfaces, Module Data Type
|
||||||
|
@section Modules and Environments
|
||||||
|
|
||||||
|
An environment belongs to a specific module, which can be determined by
|
||||||
|
calling @code{environment-module}.
|
||||||
|
|
||||||
|
@deffn procedure environment-module env
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Modules Miscallenea, , Modules and Environments, Module Data Type
|
||||||
|
@section Modules Miscallenea
|
||||||
|
|
||||||
|
This chapter contains all miscellaneous information and procedure
|
||||||
|
documentation which I have not been able to include elsewhere. If
|
||||||
|
someone knows how to include them into other chapters, suggestions are
|
||||||
|
welcome.
|
||||||
|
|
||||||
|
@deffn procedure set-system-module! m s
|
||||||
|
Set the @code{system-module} property of the module @var{m} to @var{s}.
|
||||||
|
@var{s} should be a module telling whehter @var{m} is a system module or
|
||||||
|
not. System modules are treated specially in some cases, for example
|
||||||
|
procedures defined in system modules are excluded from backtraces.
|
||||||
|
FIXME: Is this last sentence true?
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Modules and Evaluation, Index, Module Data Type, Top
|
||||||
|
@chapter Modules and Evaluation
|
||||||
|
|
||||||
|
Up to here, we have seen how modules are implemented as a data type,
|
||||||
|
which can be manipulated by C and Scheme code to implement module system
|
||||||
|
work like providing private and public name spaces, loading of modules
|
||||||
|
and creating new modules.
|
||||||
|
|
||||||
|
This chapter will describe the connection between the module system and
|
||||||
|
the Guile evaluator. Top-level variables (that is, variables not
|
||||||
|
lexically bound) need to be resolved in the current module, and if not
|
||||||
|
defined there, in the used modules, and so on, until the root module has
|
||||||
|
been asked for the bindings.
|
||||||
|
|
||||||
|
First, we have to recall how Guile normally figures out the location for
|
||||||
|
a given variable when evaluating a form. The evaluator starts by
|
||||||
|
scanning the lexical environment it maintains. It first looks in each
|
||||||
|
slot in the top-most environment frame, continuing in the next frame and
|
||||||
|
so on, until it reaches the end of the lexical environment chain.
|
||||||
|
|
||||||
|
The @sc{car} of the last pair of the environment chain is either
|
||||||
|
@code{#f}, or it is a procedure. When it is @code{#f}, the normal
|
||||||
|
system obarray is searched for the variable, otherwise the procedure is
|
||||||
|
called for returning the requested variable. This procedure is the
|
||||||
|
current module's @dfn{eval closure}, and is responsible for searching a
|
||||||
|
variable's binding, installing it if necessary.
|
||||||
|
|
||||||
|
When a variable is finally found, the reference to the variable in the
|
||||||
|
currently executed Scheme code is replaced by a special value (a
|
||||||
|
so-called @code{gloc}), so that this environment search is not necessary
|
||||||
|
the next time the variable is looked up.
|
||||||
|
|
||||||
|
|
||||||
|
@c ===================================================================
|
||||||
|
|
||||||
|
@node Index, , Modules and Evaluation, Top
|
||||||
|
@comment node-name, next, previous, up
|
||||||
|
@unnumbered Index
|
||||||
|
|
||||||
|
@printindex cp
|
||||||
|
|
||||||
|
@contents
|
||||||
|
|
||||||
|
@bye
|
Loading…
Add table
Add a link
Reference in a new issue