+Add all @var{variable}s (which must be symbols or pairs of symbols) to
+the list of re-exported bindings of the current module. Pairs of
+symbols are handled as in @code{export}. Re-exported bindings must be
+imported by the current module from some other module.
+@end deffn
+
+@deffn syntax export! variable @dots{}
+Like @code{export}, but marking the exported variables as replacing.
+Using a module with replacing bindings will cause any existing bindings
+to be replaced without issuing any warnings. See the discussion of
+@code{#:replace} above.
+@end deffn
+
+@node Modules and the File System
+@subsection Modules and the File System
+
+Typical programs only use a small subset of modules installed on a Guile
+system. In order to keep startup time down, Guile only loads modules
+when a program uses them, on demand.
+
+When a program evaluates @code{(use-modules (ice-9 popen))}, and the
+module is not loaded, Guile searches for a conventionally-named file
+from in the @dfn{load path}.
+
+In this case, loading @code{(ice-9 popen)} will eventually cause Guile
+to run @code{(primitive-load-path "ice-9/popen")}.
+@code{primitive-load-path} will search for a file @file{ice-9/popen} in
+the @code{%load-path} (@pxref{Load Paths}). For each directory in
+@code{%load-path}, Guile will try to find the file name, concatenated
+with the extensions from @code{%load-extensions}. By default, this will
+cause Guile to @code{stat} @file{ice-9/popen.scm}, and then
+@file{ice-9/popen}. @xref{Load Paths}, for more on
+@code{primitive-load-path}.
+
+If a corresponding compiled @file{.go} file is found in the
+@code{%load-compiled-path} or in the fallback path, and is as fresh as
+the source file, it will be loaded instead of the source file. If no
+compiled file is found, Guile may try to compile the source file and
+cache away the resulting @file{.go} file. @xref{Compilation}, for more
+on compilation.
+
+Once Guile finds a suitable source or compiled file is found, the file
+will be loaded. If, after loading the file, the module under
+consideration is still not defined, Guile will signal an error.
+
+For more information on where and how to install Scheme modules,
+@xref{Installing Site Packages}.
+
+
+@node R6RS Version References
+@subsection R6RS Version References
+
+Guile's module system includes support for locating modules based on
+a declared version specifier of the same form as the one described in
+R6RS (@pxref{Library form, R6RS Library Form,, r6rs, The Revised^6
+Report on the Algorithmic Language Scheme}). By using the
+@code{#:version} keyword in a @code{define-module} form, a module may
+specify a version as a list of zero or more exact, nonnegative integers.
+
+This version can then be used to locate the module during the module
+search process. Client modules and callers of the @code{use-modules}
+function may specify constraints on the versions of target modules by
+providing a @dfn{version reference}, which has one of the following
+forms:
+
+@lisp
+ (@var{sub-version-reference} ...)
+ (and @var{version-reference} ...)
+ (or @var{version-reference} ...)
+ (not @var{version-reference})
+@end lisp
+
+in which @var{sub-version-reference} is in turn one of:
+
+@lisp
+ (@var{sub-version})
+ (>= @var{sub-version})
+ (<= @var{sub-version})
+ (and @var{sub-version-reference} ...)
+ (or @var{sub-version-reference} ...)
+ (not @var{sub-version-reference})
+@end lisp
+
+in which @var{sub-version} is an exact, nonnegative integer as above. A
+version reference matches a declared module version if each element of
+the version reference matches a corresponding element of the module
+version, according to the following rules:
+
+@itemize @bullet
+@item
+The @code{and} sub-form matches a version or version element if every
+element in the tail of the sub-form matches the specified version or
+version element.
+
+@item
+The @code{or} sub-form matches a version or version element if any
+element in the tail of the sub-form matches the specified version or
+version element.
+
+@item
+The @code{not} sub-form matches a version or version element if the tail
+of the sub-form does not match the version or version element.
+
+@item
+The @code{>=} sub-form matches a version element if the element is
+greater than or equal to the @var{sub-version} in the tail of the
+sub-form.
+
+@item
+The @code{<=} sub-form matches a version element if the version is less
+than or equal to the @var{sub-version} in the tail of the sub-form.
+
+@item
+A @var{sub-version} matches a version element if one is @var{eqv?} to
+the other.
+@end itemize
+
+For example, a module declared as:
+
+@lisp
+ (define-module (mylib mymodule) #:version (1 2 0))
+@end lisp
+
+would be successfully loaded by any of the following @code{use-modules}
+expressions:
+
+@lisp
+ (use-modules ((mylib mymodule) #:version (1 2 (>= 0))))
+ (use-modules ((mylib mymodule) #:version (or (1 2 0) (1 2 1))))
+ (use-modules ((mylib mymodule) #:version ((and (>= 1) (not 2)) 2 0)))
+@end lisp
+
+
+@node R6RS Libraries
+@subsection R6RS Libraries
+
+In addition to the API described in the previous sections, you also
+have the option to create modules using the portable @code{library} form
+described in R6RS (@pxref{Library form, R6RS Library Form,, r6rs, The
+Revised^6 Report on the Algorithmic Language Scheme}), and to import
+libraries created in this format by other programmers. Guile's R6RS
+library implementation takes advantage of the flexibility built into the
+module system by expanding the R6RS library form into a corresponding
+Guile @code{define-module} form that specifies equivalent import and
+export requirements and includes the same body expressions. The library
+expression:
+
+@lisp
+ (library (mylib (1 2))
+ (import (otherlib (3)))
+ (export mybinding))
+@end lisp
+
+is equivalent to the module definition:
+
+@lisp
+ (define-module (mylib)
+ #:version (1 2)
+ #:use-module ((otherlib) #:version (3))
+ #:export (mybinding))
+@end lisp
+
+Central to the mechanics of R6RS libraries is the concept of import
+and export @dfn{levels}, which control the visibility of bindings at
+various phases of a library's lifecycle --- macros necessary to
+expand forms in the library's body need to be available at expand
+time; variables used in the body of a procedure exported by the
+library must be available at runtime. R6RS specifies the optional
+@code{for} sub-form of an @emph{import set} specification (see below)
+as a mechanism by which a library author can indicate that a
+particular library import should take place at a particular phase
+with respect to the lifecycle of the importing library.
+
+Guile's library implementation uses a technique called
+@dfn{implicit phasing} (first described by Abdulaziz Ghuloum and R.
+Kent Dybvig), which allows the expander and compiler to automatically
+determine the necessary visibility of a binding imported from another
+library. As such, the @code{for} sub-form described below is ignored by
+Guile (but may be required by Schemes in which phasing is explicit).
+
+@deffn {Scheme Syntax} library name (export export-spec ...) (import import-spec ...) body ...
+Defines a new library with the specified name, exports, and imports,
+and evaluates the specified body expressions in this library's
+environment.
+
+The library @var{name} is a non-empty list of identifiers, optionally
+ending with a version specification of the form described above
+(@pxref{Creating Guile Modules}).
+
+Each @var{export-spec} is the name of a variable defined or imported
+by the library, or must take the form
+@code{(rename (internal-name external-name) ...)}, where the
+identifier @var{internal-name} names a variable defined or imported
+by the library and @var{external-name} is the name by which the
+variable is seen by importing libraries.
+
+Each @var{import-spec} must be either an @dfn{import set} (see below)
+or must be of the form @code{(for import-set import-level ...)},
+where each @var{import-level} is one of:
+
+@lisp
+ run
+ expand
+ (meta @var{level})
+@end lisp
+
+where @var{level} is an integer. Note that since Guile does not
+require explicit phase specification, any @var{import-set}s found
+inside of @code{for} sub-forms will be ``unwrapped'' during
+expansion and processed as if they had been specified directly.
+
+Import sets in turn take one of the following forms:
+
+@lisp
+ @var{library-reference}
+ (library @var{library-reference})
+ (only @var{import-set} @var{identifier} ...)
+ (except @var{import-set} @var{identifier} ...)
+ (prefix @var{import-set} @var{identifier})
+ (rename @var{import-set} (@var{internal-identifier} @var{external-identifier}) ...)
+@end lisp
+
+where @var{library-reference} is a non-empty list of identifiers
+ending with an optional version reference (@pxref{R6RS Version
+References}), and the other sub-forms have the following semantics,
+defined recursively on nested @var{import-set}s:
+
+@itemize @bullet
+
+@item
+The @code{library} sub-form is used to specify libraries for import
+whose names begin with the identifier ``library.''
+
+@item
+The @code{only} sub-form imports only the specified @var{identifier}s
+from the given @var{import-set}.
+
+@item
+The @code{except} sub-form imports all of the bindings exported by
+@var{import-set} except for those that appear in the specified list
+of @var{identifier}s.
+
+@item
+The @code{prefix} sub-form imports all of the bindings exported
+by @var{import-set}, first prefixing them with the specified
+@var{identifier}.
+
+@item
+The @code{rename} sub-form imports all of the identifiers exported
+by @var{import-set}. The binding for each @var{internal-identifier}
+among these identifiers is made visible to the importing library as
+the corresponding @var{external-identifier}; all other bindings are
+imported using the names provided by @var{import-set}.
+
+@end itemize
+
+Note that because Guile translates R6RS libraries into module
+definitions, an import specification may be used to declare a
+dependency on a native Guile module --- although doing so may make
+your libraries less portable to other Schemes.
+
+@end deffn
+
+@deffn {Scheme Syntax} import import-spec ...
+Import into the current environment the libraries specified by the
+given import specifications, where each @var{import-spec} takes the
+same form as in the @code{library} form described above.
+@end deffn
+
+
+@node Variables
+@subsection Variables
+@tpindex Variables
+
+Each module has its own hash table, sometimes known as an @dfn{obarray},
+that maps the names defined in that module to their corresponding
+variable objects.
+
+A variable is a box-like object that can hold any Scheme value. It is
+said to be @dfn{undefined} if its box holds a special Scheme value that
+denotes undefined-ness (which is different from all other Scheme values,
+including for example @code{#f}); otherwise the variable is
+@dfn{defined}.
+
+On its own, a variable object is anonymous. A variable is said to be
+@dfn{bound} when it is associated with a name in some way, usually a
+symbol in a module obarray. When this happens, the name is said to be
+bound to the variable, in that module.
+
+(That's the theory, anyway. In practice, defined-ness and bound-ness
+sometimes get confused, because Lisp and Scheme implementations have
+often conflated --- or deliberately drawn no distinction between --- a
+name that is unbound and a name that is bound to a variable whose value
+is undefined. We will try to be clear about the difference and explain
+any confusion where it is unavoidable.)
+
+Variables do not have a read syntax. Most commonly they are created and
+bound implicitly by @code{define} expressions: a top-level @code{define}
+expression of the form
+
+@lisp
+(define @var{name} @var{value})
+@end lisp
+
+@noindent
+creates a variable with initial value @var{value} and binds it to the
+name @var{name} in the current module. But they can also be created
+dynamically by calling one of the constructor procedures
+@code{make-variable} and @code{make-undefined-variable}.
+
+@deffn {Scheme Procedure} make-undefined-variable
+@deffnx {C Function} scm_make_undefined_variable ()
+Return a variable that is initially unbound.
+@end deffn
+
+@deffn {Scheme Procedure} make-variable init
+@deffnx {C Function} scm_make_variable (init)
+Return a variable initialized to value @var{init}.
+@end deffn
+
+@deffn {Scheme Procedure} variable-bound? var
+@deffnx {C Function} scm_variable_bound_p (var)
+Return @code{#t} if @var{var} is bound to a value, or @code{#f}
+otherwise. Throws an error if @var{var} is not a variable object.
+@end deffn
+
+@deffn {Scheme Procedure} variable-ref var
+@deffnx {C Function} scm_variable_ref (var)
+Dereference @var{var} and return its value.
+@var{var} must be a variable object; see @code{make-variable}
+and @code{make-undefined-variable}.
+@end deffn
+
+@deffn {Scheme Procedure} variable-set! var val
+@deffnx {C Function} scm_variable_set_x (var, val)
+Set the value of the variable @var{var} to @var{val}.
+@var{var} must be a variable object, @var{val} can be any
+value. Return an unspecified value.
+@end deffn
+
+@deffn {Scheme Procedure} variable-unset! var
+@deffnx {C Function} scm_variable_unset_x (var)
+Unset the value of the variable @var{var}, leaving @var{var} unbound.
+@end deffn
+
+@deffn {Scheme Procedure} variable? obj
+@deffnx {C Function} scm_variable_p (obj)
+Return @code{#t} if @var{obj} is a variable object, else return
+@code{#f}.