summaryrefslogtreecommitdiff
path: root/doc/sources
diff options
context:
space:
mode:
authorNeil Jerram <neil@ossau.uklinux.net>2001-08-24 09:40:29 +0000
committerNeil Jerram <neil@ossau.uklinux.net>2001-08-24 09:40:29 +0000
commita0e07ba4ec86e4df014fee0666f18ece5a4d2471 (patch)
treeebe6546fc93fdcb3e2e1fdfbe55d809914b94ad8 /doc/sources
parent80fdeb4e5a869726da90c88ddce377f599515ee8 (diff)
downloadguile-a0e07ba4ec86e4df014fee0666f18ece5a4d2471.tar.gz
* Organize documentation into per-manual directories (halfway point commit).
Diffstat (limited to 'doc/sources')
-rw-r--r--doc/sources/env.texi1165
-rw-r--r--doc/sources/format.texi434
2 files changed, 1599 insertions, 0 deletions
diff --git a/doc/sources/env.texi b/doc/sources/env.texi
new file mode 100644
index 000000000..dc6bf9a40
--- /dev/null
+++ b/doc/sources/env.texi
@@ -0,0 +1,1165 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename env.info
+@settitle Top-level Environments in Guile
+@c %**end of header
+
+@setchapternewpage odd
+
+@c Changes since Jost's implementation:
+@c "finite environments" -> "leaf environments"
+@c "scm_foo_internal" -> "scm_c_foo"
+
+@c To do:
+@c add spec for soft environments
+
+@c When merged into the main manual, add cross-references for:
+@c weak references
+@c smobs (esp. module's mark and free functions)
+
+
+[[add refs for all conditions signalled]]
+
+@ifinfo
+Copyright 1999 Free Software Foundation, Inc.
+@end ifinfo
+
+@titlepage
+@sp 10
+@comment The title is printed in a large font.
+@center @titlefont{Top-level Environments in Guile}
+
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1999 Free Software Foundation, Inc.
+@end titlepage
+
+@node Top, Motivation, (dir), (dir)
+
+@menu
+* Motivation::
+* Top-Level Environments in Guile::
+* Modules::
+@end menu
+
+@node Motivation, Top-Level Environments in Guile, Top, Top
+@chapter Motivation
+
+@example
+$Id: env.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $
+@end example
+
+This is a draft proposal for a new datatype for representing top-level
+environments in Guile. Upon completion, this proposal will be posted to
+the mailing list @samp{guile@@cygnus.com} for discussion, revised in
+light of whatever insights that may produce, and eventually implemented.
+
+Note that this is @emph{not} a proposal for a module system; rather, it
+is a proposal for a data structure which encapsulates the ideas one
+needs when writing a module system, and, most importantly, a fixed
+interface which insulates the interpreter from the details of the module
+system. Using these environments, one could implement any module system
+one pleased, without changing the interpreter.
+
+I hope this text will eventually become a chapter of the Guile manual;
+thus, the description of environments in written in the present tense,
+as if it were already implemented, not in the future tense. However,
+this text does not actually describe the present state of Guile.
+
+I'm especially interested in improving the vague, rambling presentation
+of environments in the section "Modules and Environments". I'm trying
+to orient the user for the discussion that follows, but I wonder if I'm
+just confusing the issue. I would appreciate suggestions if they are
+concrete --- please provide new wording.
+
+Note also: I'm trying out a convention I'm considering for use in the
+manual. When a Scheme procedure which is directly implemented by a C
+procedure, and both are useful to call from their respective languages,
+we document the Scheme procedure only, and call it a "Primitive". If a
+Scheme function is marked as a primitive, you can derive the name of the
+corresponding C function by changing @code{-} to @code{_}, @code{!} to
+@code{_x}, @code{?} to @code{_p}, and prepending @code{scm_}. The C
+function's arguments will be all of the Scheme procedure's argumements,
+both required and optional; if the Scheme procedure takes a ``rest''
+argument, that will be a final argument to the C function. The C
+function's arguments, as well as its return type, will be @code{SCM}.
+Thus, a procedure documented like this:
+@deffn Primitive set-car! pair value
+@end deffn
+
+has a corresponding C function which would be documented like this:
+@deftypefn {Libguile function} SCM scm_set_car_x (SCM @var{pair}, SCM @var{value})
+@end deftypefn
+
+The hope is that this will be an uncluttered way to document both the C
+and Scheme interfaces, without unduly confusing users interested only in
+the Scheme level.
+
+When there is a C function which provides the same functionality as a
+primitive, but with a different interface tailored for C's needs, it
+usually has the same name as the primitive's C function, but with the
+prefix @code{scm_c_} instead of simply @code{scm_}. Thus,
+@code{scm_c_environment_ref} is almost identical to
+@code{scm_environment_ref}, except that it indicates an unbound variable
+in a manner friendlier to C code.
+
+
+
+@node Top-Level Environments in Guile, Modules, Motivation, Top
+@chapter Top-Level Environments in Guile
+
+In Guile, an environment is a mapping from symbols onto variables, and
+a variable is a location containing a value. Guile uses the datatype
+described here to represent its top-level environments.
+
+
+@menu
+* Modules and Environments:: Modules are environments, with bookkeeping.
+* Common Environment Operations:: Looking up bindings, creating bindings, etc.
+* Standard Environment Types:: Guile has some fundamental environment types.
+* Implementing Environments:: You can extend Guile with new kinds of
+ environments.
+* Switching to Environments:: Changes needed to today's Guile to
+ implement the features described here.
+@end menu
+
+@node Modules and Environments, Common Environment Operations, Top-Level Environments in Guile, Top-Level Environments in Guile
+@section Modules and Environments
+
+Guile distinguishes between environments and modules. A module is a
+unit of code sharing; it has a name, like @code{(math random)}, an
+implementation (e.g., Scheme source code, a dynamically linked library,
+or a set of primitives built into Guile), and finally, an environment
+containing the definitions which the module exports for its users.
+
+An environment, by contrast, is simply an abstract data type
+representing a mapping from symbols onto variables which the Guile
+interpreter uses to look up top-level definitions. The @code{eval}
+procedure interprets its first argument, an expression, in the context
+of its second argument, an environment.
+
+Guile uses environments to implement its module system. A module
+created by loading Scheme code might be built from several environments.
+In addition to the environment of exported definitions, such a module
+might have an internal top-level environment, containing both exported
+and private definitions, and perhaps environments for imported
+definitions alone and local definitions alone.
+
+The interface described here includes a full set of functions for
+mutating environments, and the system goes to some length to maintain
+its consistency as environments' bindings change. This is necessary
+because Guile is an interactive system. The user may create new
+definitions or modify and reload modules while Guile is running; the
+system should handle these changes in a consistent and predictable way.
+
+A typical Guile system will have several distinct top-level
+environments. (This is why we call them ``top-level'', and not
+``global''.) For example, consider the following fragment of an
+interactive Guile session:
+
+@example
+guile> (use-modules (ice-9 regex))
+guile> (define pattern "^(..+)\\1+$")
+guile> (string-match pattern "xxxx")
+#("xxxx" (0 . 4) (0 . 2))
+guile> (string-match pattern "xxxxx")
+#f
+guile>
+@end example
+@noindent
+Guile evaluates the expressions the user types in a top-level
+environment reserved for that purpose; the definition of @code{pattern}
+goes there. That environment is distinct from the one holding the
+private definitions of the @code{(ice-9 regex)} module. At the Guile
+prompt, the user does not see the module's private definitions, and the
+module is unaffected by definitions the user makes at the prompt. The
+@code{use-modules} form copies the module's public bindings into the
+user's environment.
+
+All Scheme evaluation takes place with respect to some top-level
+environment. Just as the procedure created by a @code{lambda} form
+closes over any local scopes surrounding that form, it also closes over
+the surrounding top-level environment. Thus, since the
+@code{string-match} procedure is defined in the @code{(ice-9 regex)}
+module, it closes over that module's top-level environment. Thus, when
+the user calls @code{string-match} from the Guile prompt, any free
+variables in @code{string-match}'s definition are resolved with respect
+to the module's top-level environment, not the user's.
+
+Although the Guile interaction loop maintains a ``current'' top-level
+environment in which it evaluates the user's input, it would be
+misleading to extend the concept of a ``current top-level environment''
+to the system as a whole. Each procedure closes over its own top-level
+environment, in which that procedure will find bindings for its free
+variables. Thus, the top-level environment in force at any given time
+depends on the procedure Guile happens to be executing. The global
+``current'' environment is a figment of the interaction loop's
+imagination.
+
+Since environments provide all the operations the Guile interpreter
+needs to evaluate code, they effectively insulate the interpreter from
+the details of the module system. Without changing the interpreter, you
+can implement any module system you like, as long as its efforts produce
+an environment object the interpreter can consult.
+
+Finally, environments may prove a convenient way for Guile to access the
+features of other systems. For example, one might export the The GIMP's
+Procedural Database to Guile as a custom environment type; this
+environment could create Scheme procedure objects corresponding to GIMP
+procedures, as the user referenced them.
+
+
+@node Common Environment Operations, Standard Environment Types, Modules and Environments, Top-Level Environments in Guile
+@section Common Environment Operations
+
+This section describes the common set of operations that all environment
+objects support. To create an environment object, or to perform an
+operation specific to a particular kind of environment, see
+@ref{Standard Environment Types}.
+
+In this section, the following names for formal parameters imply that
+the actual parameters must have a certain type:
+
+@table @var
+
+@item env
+an environment
+
+@item symbol
+a symbol
+
+@item proc
+a procedure
+
+@item value
+@itemx object
+an arbitrary Scheme value
+
+@end table
+
+
+@menu
+* Examining Environments::
+* Changing Environments::
+* Caching Environment Lookups::
+* Observing Changes to Environments ::
+* Environment Errors::
+@end menu
+
+@node Examining Environments, Changing Environments, Common Environment Operations, Common Environment Operations
+@subsection Examining Environments
+
+@deffn Primitive environment? object
+Return @code{#t} if @var{object} is an environment, or @code{#f} otherwise.
+@end deffn
+
+@deffn Primitive environment-ref env symbol
+Return the value of the location bound to @var{symbol} in @var{env}.
+If @var{symbol} is unbound in @var{env}, signal an @code{environment:unbound}
+error (@pxref{Environment Errors}).
+@end deffn
+
+@deffn Primitive environment-bound? env symbol
+Return @code{#t} if @var{symbol} is bound in @var{env}, or @code{#f}
+otherwise.
+@end deffn
+
+@deffn Primitive environment-fold env proc init
+Iterate over all the bindings in an environment, accumulating some value.
+
+For each binding in @var{env}, apply @var{proc} to the symbol bound, its
+value, and the result from the previous application of @var{proc}. Use
+@var{init} as @var{proc}'s third argument the first time @var{proc} is
+applied.
+
+If @var{env} contains no bindings, this function simply returns @var{init}.
+
+If @var{env} binds the symbol @var{sym1} to the value @var{val1},
+@var{sym2} to @var{val2}, and so on, then this procedure computes:
+@example
+(@var{proc} @var{sym1} @var{val1}
+ (@var{proc} @var{sym2} @var{val2}
+ ...
+ (@var{proc} @var{symn} @var{valn}
+ @var{init})))
+@end example
+
+Each binding in @var{env} is processed at most once.
+@code{environment-fold} makes no guarantees about the order in which the
+bindings are processed.
+
+If @var{env} is not modified while the iteration is taking place,
+@code{environment-fold} will apply @var{proc} to each binding in
+@var{env} exactly once.
+
+If @var{env} is modified while the iteration is taking place, we need to
+be more subtle in describing @code{environment-fold}'s behavior.
+@code{environment-fold} repeatedly applies @var{proc} to a binding which
+was present in @var{env} when @code{environment-fold} was invoked and is
+still present in @var{env}, until there are no such bindings remaining.
+(If no mutations take place, this definition is equivalent to the
+simpler one given above.) By this definition, bindings added during the
+iteration will not be passed to @var{proc}.
+
+Here is a function which, given an environment, constructs an
+association list representing that environment's bindings, using
+@code{environment-fold}:
+@example
+(define (environment->alist env)
+ (environment-fold env
+ (lambda (sym val tail)
+ (cons (cons sym val) tail))
+ '()))
+@end example
+@end deffn
+
+@deftypefn {Libguile macro} int SCM_ENVP (@var{object})
+Return non-zero if @var{object} is an environment.
+@end deftypefn
+
+@deftypefn {Libguile function} SCM scm_c_environment_ref (SCM @var{env}, SCM @var{symbol})
+This C function is identical to @code{environment-ref}, except that if
+@var{symbol} is unbound in @var{env}, it returns the value
+@code{SCM_UNDEFINED}, instead of signalling an error.
+@end deftypefn
+
+@deftypefn {Libguile function} SCM scm_c_environment_fold (SCM @var{env}, scm_environment_folder *@var{proc}, SCM @var{data}, SCM @var{init})
+This is the C-level analog of @code{environment-fold}. For each binding in
+@var{env}, make the call:
+@example
+(*@var{proc}) (@var{data}, @var{symbol}, @var{value}, @var{previous})
+@end example
+@noindent
+where @var{previous} is the value returned from the last call to
+@code{*@var{proc}}, or @var{init} for the first call. If @var{env}
+contains no bindings, return @var{init}.
+@end deftypefn
+
+@deftp {Libguile data type} scm_environment_folder SCM (SCM @var{data}, SCM @var{symbol}, SCM @var{value}, SCM @var{tail})
+The type of a folding function to pass to @code{scm_c_environment_fold}.
+@end deftp
+
+
+@node Changing Environments, Caching Environment Lookups, Examining Environments, Common Environment Operations
+@subsection Changing Environments
+
+Here are functions for changing symbols' bindings and values.
+
+Although it is common to say that an environment binds a symbol to a
+value, this is not quite accurate; an environment binds a symbol to a
+location, and the location contains a value. In the descriptions below,
+we will try to make clear how each function affects bindings and
+locations.
+
+Note that some environments may contain some immutable bindings, or may
+bind symbols to immutable locations. If you attempt to change an
+immutable binding or value, these functions will signal an
+@code{environment:immutable-binding} or
+@code{environment:immutable-location} error. However, simply because a
+binding cannot be changed via these functions does @emph{not} imply that
+it is constant. Mechanisms outside the scope of this section (say,
+re-loading a module's source code) may change a binding or value which
+is immutable via these functions.
+
+@deffn Primitive environment-define env symbol value
+Bind @var{symbol} to a new location containing @var{value} in @var{env}.
+If @var{symbol} is already bound to another location in @var{env}, that
+binding is replaced. The new binding and location are both mutable.
+The return value is unspecified.
+
+If @var{symbol} is already bound in @var{env}, and the binding is
+immutable, signal an @code{environment:immutable-binding} error.
+@end deffn
+
+@deffn Primitive environment-undefine env symbol
+Remove any binding for @var{symbol} from @var{env}. If @var{symbol} is
+unbound in @var{env}, do nothing. The return value is unspecified.
+
+If @var{symbol} is already bound in @var{env}, and the binding is
+immutable, signal an @code{environment:immutable-binding} error.
+@end deffn
+
+@deffn Primitive environment-set! env symbol value
+If @var{env} binds @var{symbol} to some location, change that location's
+value to @var{value}. The return value is unspecified.
+
+If @var{symbol} is not bound in @var{env}, signal an
+@code{environment:unbound} error. If @var{env} binds @var{symbol} to an
+immutable location, signal an @code{environment:immutable-location}
+error.
+@end deffn
+
+
+@node Caching Environment Lookups, Observing Changes to Environments , Changing Environments, Common Environment Operations
+@subsection Caching Environment Lookups
+
+Some applications refer to variables' values so frequently that the
+overhead of @code{environment-ref} and @code{environment-set!} is
+unacceptable. For example, variable reference speed is a critical
+factor in the performance of the Guile interpreter itself. If an
+application can tolerate some additional complexity, the
+@code{environment-cell} function described here can provide very
+efficient access to variable values.
+
+In the Guile interpreter, most variables are represented by pairs; the
+@sc{cdr} of the pair holds the variable's value. Thus, a variable
+reference corresponds to taking the @sc{cdr} of one of these pairs, and
+setting a variable corresponds to a @code{set-cdr!} operation. A pair
+used to represent a variable's value in this manner is called a
+@dfn{value cell}. Value cells represent the ``locations'' to which
+environments bind symbols.
+
+The @code{environment-cell} function returns the value cell bound to a
+symbol. For example, an interpreter might make the call
+@code{(environment-cell @var{env} @var{symbol} #t)} to find the value
+cell which @var{env} binds to @var{symbol}, and then use @code{cdr} and
+@code{set-cdr!} to reference and assign to that variable, instead of
+calling @code{environment-ref} or @var{environment-set!} for each
+variable reference.
+
+There are a few caveats that apply here:
+
+@itemize @bullet
+
+@item
+Environments are not required to represent variables' values using value
+cells. An environment is free to return @code{#f} in response to a
+request for a symbol's value cell; in this case, the caller must use
+@code{environment-ref} and @code{environment-set!} to manipulate the
+variable.
+
+@item
+An environment's binding for a symbol may change. For example, the user
+could override an imported variable with a local definition, associating
+a new value cell with that symbol. If an interpreter has used
+@code{environment-cell} to obtain the variable's value cell, it no
+longer needs to use @code{environment-ref} and @code{environment-set!}
+to access the variable, and it may not see the new binding.
+
+Thus, code which uses @code{environment-cell} should almost always use
+@code{environment-observe} to track changes to the symbol's binding;
+this is the additional complexity hinted at above. @xref{Observing
+Changes to Environments}.
+
+@item
+Some variables should be immutable. If a program uses
+@code{environment-cell} to obtain the value cell of such a variable,
+then it is impossible for the environment to prevent the program from
+changing the variable's value, using @code{set-cdr!}. However, this is
+discouraged; it is probably better to redesign the interface than to
+disregard such a request. To make it easy for programs to honor the
+immutability of a variable, @code{environment-cell} takes an argument
+indicating whether the caller intends to mutate the cell's value; if
+this argument is true, then @code{environment-cell} signals an
+@code{environment:immutable-location} error.
+
+Programs should therefore make separate calls to @code{environment-cell}
+to obtain value cells for reference and for assignment. It is incorrect
+for a program to call @code{environment-cell} once to obtain a value
+cell, and then use that cell for both reference and mutation.
+
+@end itemize
+
+@deffn Primitive environment-cell env symbol for-write
+Return the value cell which @var{env} binds to @var{symbol}, or
+@code{#f} if the binding does not live in a value cell.
+
+The argument @var{for-write} indicates whether the caller intends to
+modify the variable's value by mutating the value cell. If the variable
+is immutable, then @code{environment-cell} signals an
+@code{environment:immutable-location} error.
+
+If @var{symbol} is unbound in @var{env}, signal an @code{environment:unbound}
+error.
+
+If you use this function, you should consider using
+@code{environment-observe}, to be notified when @code{symbol} gets
+re-bound to a new value cell, or becomes undefined.
+@end deffn
+
+@deftypefn {Libguile function} SCM scm_c_environment_cell (SCM @var{env}, SCM @var{symbol}, int for_write)
+This C function is identical to @code{environment-cell}, except that if
+@var{symbol} is unbound in @var{env}, it returns the value
+@code{SCM_UNDEFINED}, instead of signalling an error.
+@end deftypefn
+
+[[After we have some experience using this, we may find that we want to
+be able to explicitly ask questions like, "Is this variable mutable?"
+without the annoyance of error handling. But maybe this is fine.]]
+
+
+@node Observing Changes to Environments , Environment Errors, Caching Environment Lookups, Common Environment Operations
+@subsection Observing Changes to Environments
+
+The procedures described here allow you to add and remove @dfn{observing
+procedures} for an environment.
+
+
+@menu
+* Registering Observing Procedures::
+* Observations and Garbage Collection::
+* Observing Environments from C Code::
+@end menu
+
+@node Registering Observing Procedures, Observations and Garbage Collection, Observing Changes to Environments , Observing Changes to Environments
+@subsubsection Registering Observing Procedures
+
+A program may register an @dfn{observing procedure} for an environment,
+which will be called whenever a binding in a particular environment
+changes. For example, if the user changes a module's source code and
+re-loads the module, other parts of the system may want to throw away
+information they have cached about the bindings of the older version of
+the module. To support this, each environment retains a set of
+observing procedures which it will invoke whenever its bindings change.
+We say that these procedures @dfn{observe} the environment's bindings.
+You can register new observing procedures for an environment using
+@code{environment-observe}.
+
+@deffn Primitive environment-observe env proc
+Whenever @var{env}'s bindings change, apply @var{proc} to @var{env}.
+
+This function returns an object, @var{token}, which you can pass to
+@code{environment-unobserve} to remove @var{proc} from the set of
+procedures observing @var{env}. The type and value of @var{token} is
+unspecified.
+@end deffn
+
+@deffn Primitive environment-unobserve token
+Cancel the observation request which returned the value @var{token}.
+The return value is unspecified.
+
+If a call @code{(environment-observe @var{env} @var{proc})} returns
+@var{token}, then the call @code{(environment-unobserve @var{token})}
+will cause @var{proc} to no longer be called when @var{env}'s bindings
+change.
+@end deffn
+
+There are some limitations on observation:
+@itemize @bullet
+@item
+These procedures do not allow you to observe specific bindings; you
+can only observe an entire environment.
+@item
+These procedures observe bindings, not locations. There is no way
+to receive notification when a location's value changes, using these
+procedures.
+@item
+These procedures do not promise to call the observing procedure for each
+individual binding change. However, if multiple bindings do change
+between calls to the observing procedure, those changes will appear
+atomic to the entire system, not just to a few observing procedures.
+@item
+Since a single environment may have several procedures observing it, a
+correct design obviously may not assume that nothing else in the system
+has yet observed a given change.
+@end itemize
+
+(One weakness of this observation architecture is that observing
+procedures make no promises to the observer. That's fine if you're just
+trying to implement an accurate cache, but too weak to implement things
+that walk the environment tree.)
+
+@node Observations and Garbage Collection, Observing Environments from C Code, Registering Observing Procedures, Observing Changes to Environments
+@subsubsection Observations and Garbage Collection
+
+When writing observing procedures, pay close attention to garbage
+collection issues. If you use @code{environment-observe} to register
+observing procedures for an environment, the environment will hold a
+reference to those procedures; while that environment is alive, its
+observing procedures will live, as will any data they close over. If
+this is not appropriate, you can use the @code{environment-observe-weak}
+procedure to create a weak reference from the environment to the
+observing procedure.
+
+For example, suppose an interpreter uses @code{environment-cell} to
+reference variables efficiently, as described above in @ref{Caching
+Environment Lookups}. That interpreter must register observing
+procedures to track changes to the environment. If those procedures
+retain any reference to the data structure representing the program
+being interpreted, then that structure cannot be collected as long as
+the observed environment lives. This is almost certainly incorrect ---
+if there are no other references to the structure, it can never be
+invoked, so it should be collected. In this case, the interpreter
+should register its observing procedure using
+@code{environment-observe-weak}, and retain a pointer to it from the
+code it updates. Thus, when the code is no longer referenced elsewhere
+in the system, the weak link will be broken, and Guile will collect the
+code (and its observing procedure).
+
+@deffn Primitive environment-observe-weak env proc
+This function is the same as @code{environment-observe}, except that the
+reference @var{env} retains to @var{proc} is a weak reference. This
+means that, if there are no other live, non-weak references to
+@var{proc}, it will be garbage-collected, and dropped from @var{env}'s
+list of observing procedures.
+@end deffn
+
+
+@node Observing Environments from C Code, , Observations and Garbage Collection, Observing Changes to Environments
+@subsubsection Observing Environments from C Code
+
+It is also possible to write code that observes an environment in C.
+The @code{scm_c_environment_observe} function registers a C
+function to observe an environment. The typedef
+@code{scm_environment_observer} is the type a C observer function must
+have.
+
+@deftypefn {Libguile function} SCM scm_c_environment_observe (SCM @var{env}, scm_environment_observer *proc, SCM @var{data}, int weak_p)
+This is the C-level analog of the Scheme function
+@code{environment-observe}. Whenever @var{env}'s bindings change, call
+the function @var{proc}, passing it @var{env} and @var{data}. If
+@var{weak_p} is non-zero, @var{env} will retain only a weak reference to
+@var{data}, and if @var{data} is garbage collected, the entire
+observation will be dropped.
+
+This function returns a token, with the same meaning as those returned
+by @code{environment-observe}.
+@end deftypefn
+
+@deftp {Libguile data type} scm_environment_observer void (SCM @var{env}, SCM @var{data})
+The type for observing functions written in C. A function meant to be
+passed to @code{scm_c_environment_observe} should have the type
+@code{scm_environment_observer}.
+@end deftp
+
+Note that, like all other primitives, @code{environment-observe} is also
+available from C, under the name @code{scm_environment_observe}.
+
+
+@node Environment Errors, , Observing Changes to Environments , Common Environment Operations
+@subsection Environment Errors
+
+Here are the error conditions signalled by the environment routines
+described above. In these conditions, @var{func} is a string naming a
+particular procedure.
+
+@deffn Condition environment:unbound func message args env symbol
+By calling @var{func}, the program attempted to retrieve the value of
+@var{symbol} in @var{env}, but @var{symbol} is unbound in @var{env}.
+@end deffn
+
+@deffn Condition environment:immutable-binding func message args env symbol
+By calling @var{func}, the program attempted to change the binding of
+@var{symbol} in @var{env}, but that binding is immutable.
+@end deffn
+
+@deffn Condition environment:immutable-location func message args env symbol
+By calling @var{func}, the program attempted to change the value of
+the location to which @var{symbol} is bound in @var{env}, but that
+location is immutable.
+@end deffn
+
+
+@node Standard Environment Types, Implementing Environments, Common Environment Operations, Top-Level Environments in Guile
+@section Standard Environment Types
+
+Guile supports several different kinds of environments. The operations
+described above are actually only the common functionality provided by
+all the members of a family of environment types, each designed for a
+separate purpose.
+
+Each environment type has a constructor procedure for building elements
+of that type, and extends the set of common operations with its own
+procedures, providing specialized functions. For an example of how
+these environment types work together, see @ref{Modules of Interpreted
+Scheme Code}.
+
+Guile allows users to define their own environment types. Given a set
+of procedures that implement the common environment operations, Guile
+will construct a new environment object based on those procedures.
+
+@menu
+* Leaf Environments:: A simple set of bindings.
+* Eval Environments:: Local definitions, shadowing
+ imported definitions.
+* Import Environments:: The union of a list of environments.
+* Export Environments:: A selected subset of an environment.
+* General Environments:: Environments implemented by user
+ functions.
+@end menu
+
+@node Leaf Environments, Eval Environments, Standard Environment Types, Standard Environment Types
+@subsection Leaf Environments
+
+A @dfn{leaf} environment is simply a mutable set of definitions. A mutable
+environment supports no operations beyond the common set.
+
+@deffn Primitive make-leaf-environment
+Create a new leaf environment, containing no bindings. All bindings
+and locations in the new environment are mutable.
+@end deffn
+
+@deffn Primitive leaf-environment? object
+Return @code{#t} if @var{object} is a leaf environment, or @var{#f}
+otherwise.
+@end deffn
+
+
+In Guile, each module of interpreted Scheme code uses a leaf
+environment to hold the definitions made in that module.
+
+Leaf environments are so named because their bindings are not computed
+from the contents of other environments. Most other environment types
+have no bindings of their own, but compute their binding sets based on
+those of their operand environments. Thus, the environments in a
+running Guile system form a tree, with interior nodes computing their
+contents from their child nodes. Leaf environments are the leaves of
+such trees.
+
+
+@node Eval Environments, Import Environments, Leaf Environments, Standard Environment Types
+@subsection Eval Environments
+
+A module's source code refers to definitions imported from other
+modules, and definitions made within itself. An @dfn{eval} environment
+combines two environments --- a @dfn{local} environment and an
+@dfn{imported} environment --- to produce a new environment in which
+both sorts of references can be resolved.
+
+@deffn Primitive make-eval-environment local imported
+Return a new environment object @var{eval} whose bindings are the union
+of the bindings in the environments @var{local} and @var{imported}, with
+bindings from @var{local} taking precedence. Definitions made in
+@var{eval} are placed in @var{local}.
+
+Applying @code{environment-define} or @code{environment-undefine} to
+@var{eval} has the same effect as applying the procedure to @var{local}.
+This means that applying @code{environment-undefine} to a symbol bound
+in @var{imported} and free in @var{local} has no effect on the bindings
+visible in @var{eval}, which may be surprising.
+
+Note that @var{eval} incorporates @var{local} and @var{imported}
+@emph{by reference} --- if, after creating @var{eval}, the program
+changes the bindings of @var{local} or @var{imported}, those changes
+will be visible in @var{eval}.
+
+Since most Scheme evaluation takes place in @var{eval} environments,
+they transparenty cache the bindings received from @var{local} and
+@var{imported}. Thus, the first time the program looks up a symbol in
+@var{eval}, @var{eval} may make calls to @var{local} or @var{imported}
+to find their bindings, but subsequent references to that symbol will be
+as fast as references to bindings in leaf environments.
+
+In typical use, @var{local} will be a leaf environment, and
+@var{imported} will be an import environment, described below.
+@end deffn
+
+@deffn Primitive eval-environment? object
+Return @code{#t} if @var{object} is an eval environment, or @code{#f}
+otherwise.
+@end deffn
+
+@deffn Primitive eval-environment-local env
+@deffnx Primitive eval-environment-imported env
+Return the @var{local} or @var{imported} environment of @var{env};
+@var{env} must be an eval environment.
+@end deffn
+
+
+@node Import Environments, Export Environments, Eval Environments, Standard Environment Types
+@subsection Import Environments
+
+An @dfn{import} environment combines the bindings of a set of
+argument environments, and checks for naming clashes.
+
+@deffn Primitive make-import-environment imports conflict-proc
+Return a new environment @var{imp} whose bindings are the union of the
+bindings from the environments in @var{imports}; @var{imports} must be a
+list of environments. That is, @var{imp} binds @var{symbol} to
+@var{location} when some element of @var{imports} does.
+
+If two different elements of @var{imports} have a binding for the same
+symbol, apply @var{conflict-proc} to the two environments. If the bindings
+of any of the @var{imports} ever changes, check for conflicts again.
+
+All bindings in @var{imp} are immutable. If you apply
+@code{environment-define} or @code{environment-undefine} to @var{imp},
+Guile will signal an @code{environment:immutable-binding} error.
+However, notice that the set of bindings in @var{imp} may still change,
+if one of its imported environments changes.
+@end deffn
+
+@deffn Primitive import-environment? object
+Return @code{#t} if @var{object} is an import environment, or @code{#f}
+otherwise.
+@end deffn
+
+@deffn Primitive import-environment-imports env
+Return the list of @var{env}'s imported environments; @var{env} must be
+an import env.
+@end deffn
+
+@deffn Primitive import-environment-set-imports! env imports
+Change @var{env}'s list of imported environments to @var{imports}, and
+check for conflicts.
+@end deffn
+
+I'm not at all sure about the way @var{conflict-proc} works. I think
+module systems should warn you if it seems you're likely to get the
+wrong binding, but exactly how and when those warnings should be
+generated, I don't know.
+
+
+@node Export Environments, General Environments, Import Environments, Standard Environment Types
+@subsection Export Environments
+
+An export environment restricts an environment a specified set of
+bindings.
+
+@deffn Primitive make-export-environment private signature
+Return a new environment @var{exp} containing only those bindings in
+@var{private} whose symbols are present in @var{signature}. The
+@var{private} argument must be an environment.
+
+The environment @var{exp} binds @var{symbol} to @var{location} when
+@var{env} does, and @var{symbol} is exported by @var{signature}.
+
+@var{Signature} is a list specifying which of the bindings in
+@var{private} should be visible in @var{exp}. Each element of
+@var{signature} should be a list of the form:
+@example
+(@var{symbol} @var{attribute} ...)
+@end example
+@noindent
+where each @var{attribute} is one of the following:
+@table @asis
+@item the symbol @code{mutable-location}
+@var{exp} should treat the location bound to @var{symbol} as mutable.
+That is, @var{exp} will pass calls to @var{env-set!} or
+@code{environment-cell} directly through to @var{private}.
+
+@item the symbol @code{immutable-location}
+@var{exp} should treat the location bound to @var{symbol} as immutable.
+If the program applies @code{environment-set!} to @var{exp} and
+@var{symbol}, or calls @code{environment-cell} to obtain a writable
+value cell, @code{environment-set!} will signal an
+@code{environment:immutable-location} error.
+
+Note that, even if an export environment treats a location as immutable,
+the underlying environment may treat it as mutable, so its value may
+change.
+@end table
+
+It is an error for an element of @var{signature} to specify both
+@code{mutable-location} and @code{immutable-location}. If neither is
+specified, @code{immutable-location} is assumed.
+
+As a special case, if an element of @var{signature} is a lone symbol
+@var{sym}, it is equivalent to an element of the form
+@code{(@var{sym})}.
+
+All bindings in @var{exp} are immutable. If you apply
+@code{environment-define} or @code{environment-undefine} to @var{exp},
+Guile will signal an @code{environment:immutable-binding} error.
+However, notice that the set of bindings in @var{exp} may still change,
+if the bindings in @var{private} change.
+@end deffn
+
+@deffn Primitive export-environment? object
+Return @code{#t} if @var{object} is an export environment, or @code{#f}
+otherwise.
+@end deffn
+
+@deffn Primitive export-environment-private env
+@deffnx Primitive export-environment-set-private! env
+@deffnx Primitive export-environment-signature env
+@deffnx Primitive export-environment-set-signature! env
+Accessors and mutators for the private environment and signature of
+@var{env}; @var{env} must be an export environment.
+@end deffn
+
+
+@node General Environments, , Export Environments, Standard Environment Types
+@subsection General Environments
+
+[[user provides the procedures]]
+[[A observers B and C; B observes C; C changes; A should only be
+notified once, right?]]
+[[observation loops?]]
+
+@node Implementing Environments, Switching to Environments, Standard Environment Types, Top-Level Environments in Guile
+@section Implementing Environments
+
+This section describes how to implement new environment types in Guile.
+
+Guile's internal representation of environments allows you to extend
+Guile with new kinds of environments without modifying Guile itself.
+Every environment object carries a pointer to a structure of pointers to
+functions implementing the common operations for that environment. The
+procedures @code{environment-ref}, @code{environment-set!}, etc. simply
+find this structure and invoke the appropriate function.
+
+[[It would be nice to have an example around here. How about a
+persistent environment, bound to a directory, where ref and set actually
+access files? Ref on a directory would return another
+environment... Hey, let's import my home directory!]]
+
+
+@menu
+* Environment Function Tables::
+* Environment Data::
+* Environment Example::
+@end menu
+
+
+@node Environment Function Tables, Environment Data, Implementing Environments, Implementing Environments
+@subsection Environment Function Tables
+
+An environment object is a smob whose @sc{cdr} is a pointer to a pointer
+to a @code{struct environment_funcs}:
+@example
+struct environment_funcs @{
+ SCM (*ref) (SCM self, SCM symbol);
+ SCM (*fold) (SCM self, scm_environment_folder *proc, SCM data, SCM init);
+ void (*define) (SCM self, SCM symbol, SCM value);
+ void (*undefine) (SCM self, SCM symbol);
+ void (*set) (SCM self, SCM symbol, SCM value);
+ SCM (*cell) (SCM self, SCM symbol, int for_write);
+ SCM (*observe) (SCM self, scm_environment_observer *proc, SCM data, int weak_p);
+ void (*unobserve) (SCM self, SCM token);
+ SCM (*mark) (SCM self);
+ scm_sizet (*free) (SCM self);
+ int (*print) (SCM self, SCM port, scm_print_state *pstate);
+@};
+@end example
+
+You can use the following macro to access an environment's function table:
+
+@deftypefn {Libguile macro} struct environment_funcs *SCM_ENVIRONMENT_FUNCS (@var{env})
+Return a pointer to the @code{struct environment_func} for the environment
+@var{env}. If @var{env} is not an environment object, the behavior of
+this macro is undefined.
+@end deftypefn
+
+Here is what each element of @var{env_funcs} must do to correctly
+implement an environment. In all of these calls, @var{self} is the
+environment whose function is being invoked.
+
+@table @code
+
+@item SCM ref (SCM @var{self}, SCM @var{symbol});
+This function must have the effect described above for the C call:
+@example
+scm_c_environment_ref (@var{self}, @var{symbol})
+@end example
+@xref{Examining Environments}.
+
+Note that the @code{ref} element of a @code{struct environment_funcs}
+may be zero if a @code{cell} function is provided.
+
+@item SCM fold (SCM self, scm_environment_folder *proc, SCM data, SCM init);
+This function must have the effect described above for the C call:
+@example
+scm_c_environment_fold (@var{self}, @var{proc}, @var{data}, @var{init})
+@end example
+@xref{Examining Environments}.
+
+@item void define (SCM self, SCM symbol, SCM value);
+This function must have the effect described above for the Scheme call:
+@example
+(environment-define @var{self} @var{symbol} @var{value})
+@end example
+@xref{Changing Environments}.
+
+@item void undefine (SCM self, SCM symbol);
+This function must have the effect described above for the Scheme call:
+@example
+(environment-undefine @var{self} @var{symbol})
+@end example
+@xref{Changing Environments}.
+
+@item void set (SCM self, SCM symbol, SCM value);
+This function must have the effect described above for the Scheme call:
+@example
+(environment-set! @var{self} @var{symbol} @var{value})
+@end example
+@xref{Changing Environments}.
+
+Note that the @code{set} element of a @code{struct environment_funcs}
+may be zero if a @code{cell} function is provided.
+
+@item SCM cell (SCM self, SCM symbol, int for_write);
+This function must have the effect described above for the C call:
+@example
+scm_c_environment_cell (@var{self}, @var{symbol})
+@end example
+@xref{Caching Environment Lookups}.
+
+@item SCM observe (SCM self, scm_environment_observer *proc, SCM data, int weak_p);
+This function must have the effect described above for the C call:
+@example
+scm_c_environment_observe (@var{env}, @var{proc}, @var{data}, @var{weak_p})
+@end example
+@xref{Observing Changes to Environments}.
+
+@item void unobserve (SCM self, SCM token);
+Cancel the request to observe @var{self} that returned @var{token}.
+@xref{Observing Changes to Environments}.
+
+@item SCM mark (SCM self);
+Set the garbage collection mark all Scheme cells referred to by
+@var{self}. Assume that @var{self} itself is already marked. Return a
+final object to be marked recursively.
+
+@item scm_sizet free (SCM self);
+Free all non-cell storage associated with @var{self}; return the number
+of bytes freed that were obtained using @code{scm_must_malloc} or
+@code{scm_must_realloc}.
+
+@item SCM print (SCM self, SCM port, scm_print_state *pstate);
+Print an external representation of @var{self} on @var{port}, passing
+@var{pstate} to any recursive calls to the object printer.
+
+@end table
+
+
+@node Environment Data, Environment Example, Environment Function Tables, Implementing Environments
+@subsection Environment Data
+
+When you implement a new environment type, you will likely want to
+associate some data of your own design with each environment object.
+Since ANSI C promises that casts will safely convert between a pointer
+to a structure and a pointer to its first element, you can have the
+@sc{cdr} of an environment smob point to your structure, as long as your
+structure's first element is a pointer to a @code{struct
+environment_funcs}. Then, your code can use the macro below to retrieve
+a pointer to the structure, and cast it to the appropriate type.
+
+@deftypefn {Libguile macro} struct environment_funcs **SCM_ENVIRONMENT_DATA (@var{env})
+Return the @sc{cdr} of @var{env}, as a pointer to a pointer to an
+@code{environment_funcs} structure.
+@end deftypefn
+
+@node Environment Example, , Environment Data, Implementing Environments
+@subsection Environment Example
+
+[[perhaps a simple environment based on association lists]]
+
+
+@node Switching to Environments, , Implementing Environments, Top-Level Environments in Guile
+@section Switching to Environments
+
+Here's what we'd need to do to today's Guile to install the system
+described above. This work would probably be done on a branch, because
+it involves crippling Guile while a lot of work gets done. Also, it
+could change the default set of bindings available pretty drastically,
+so the next minor release should not contain these changes.
+
+After each step here, we should have a Guile that we can at least
+interact with, perhaps with some limitations.
+
+@itemize @bullet
+
+@item
+For testing purposes, make an utterly minimal version of
+@file{boot-9.scm}: no module system, no R5RS, nothing. I think a simple
+REPL is all we need.
+
+@item
+Implement the environment datatypes in libguile, and test them using
+this utterly minimal system.
+
+@item
+Change the interpreter to use the @code{environment-cell} and
+@code{environment-observe} instead of the symbol value slots,
+first-class variables, etc. Modify the rest of libguile as necessary to
+register all the primitives in a single environment. We'll segregate
+them into modules later.
+
+@item
+Reimplement the current module system in terms of environments. It
+should still be in Scheme.
+
+@item
+Reintegrate the rest of @file{boot-9.scm}. This might be a good point
+to move it into modules.
+
+@item
+Do some profiling and optimization.
+
+@end itemize
+
+Once this is done, we can make the following simplifications to Guile:
+
+@itemize @bullet
+
+@item
+A good portion of symbols.c can go away. Symbols no longer need value
+slots. The mismash of @code{scm_sym2ovcell},
+@code{scm_intern_obarray_soft}, etc. can go away. @code{intern} becomes
+simpler.
+
+@item
+Remove first-class variables: @file{variables.c} and @file{variables.h}.
+
+@item
+Organize the primitives into environments.
+
+@item
+The family of environment types is clearly an abstract class/concrete
+subclass arrangement. We should provide GOOPS classes/metaclasses that
+make defining new environment types easy and consistent.
+
+@end itemize
+
+
+
+@node Modules, , Top-Level Environments in Guile, Top
+@chapter Modules
+
+The material here is just a sketch. Don't take it too seriously. The
+point is that environments allow us to experiment without getting
+tangled up with the interpreter.
+
+@menu
+* Modules of Guile Primitives::
+* Modules of Interpreted Scheme Code::
+@end menu
+
+@node Modules of Guile Primitives, Modules of Interpreted Scheme Code, Modules, Modules
+@section Modules of Guile Primitives
+
+@node Modules of Interpreted Scheme Code, , Modules of Guile Primitives, Modules
+@section Modules of Interpreted Scheme Code
+
+If a module is implemented by interpreted Scheme code, Guile represents
+it using several environments:
+
+@table @asis
+
+@item the @dfn{local} environment
+This environment holds all the definitions made locally by the module,
+both public and private.
+
+@item the @dfn{import} environment
+This environment holds all the definitions this module imports from
+other modules.
+
+@item the @dfn{evaluation} environment
+This is the environment in which the module's code is actually
+evaluated, and the one closed over by the module's procedures, both
+public and private. Its bindings are the union of the @var{local} and
+@var{import} environments, with local bindings taking precedence.
+
+@item the @dfn{exported} environment
+This environment holds the module's public definitions. This is the
+only environment that the module's users have access to. It is the
+@var{evaluation} environment, restricted to the set of exported
+definitions.
+
+@end table
+
+Each of these environments is implemented using a separate environment
+type. Some of these types, like the evaluation and import environments,
+actually just compute their bindings by consulting other environments;
+they have no bindings in their own right. They implement operations
+like @code{environment-ref} and @code{environment-define} by passing
+them through to the environments from which they are derived. For
+example, the evaluation environment will pass definitions through to the
+local environment, and search for references and assignments first in
+the local environment, and then in the import environment.
+
+
+
+@bye
diff --git a/doc/sources/format.texi b/doc/sources/format.texi
new file mode 100644
index 000000000..122e0453d
--- /dev/null
+++ b/doc/sources/format.texi
@@ -0,0 +1,434 @@
+
+@menu
+* Format Interface::
+* Format Specification::
+@end menu
+
+@node Format Interface, Format Specification, Format, Format
+@subsection Format Interface
+
+@defun format destination format-string . arguments
+An almost complete implementation of Common LISP format description
+according to the CL reference book @cite{Common LISP} from Guy L.
+Steele, Digital Press. Backward compatible to most of the available
+Scheme format implementations.
+
+Returns @code{#t}, @code{#f} or a string; has side effect of printing
+according to @var{format-string}. If @var{destination} is @code{#t},
+the output is to the current output port and @code{#t} is returned. If
+@var{destination} is @code{#f}, a formatted string is returned as the
+result of the call. NEW: If @var{destination} is a string,
+@var{destination} is regarded as the format string; @var{format-string} is
+then the first argument and the output is returned as a string. If
+@var{destination} is a number, the output is to the current error port
+if available by the implementation. Otherwise @var{destination} must be
+an output port and @code{#t} is returned.@refill
+
+@var{format-string} must be a string. In case of a formatting error
+format returns @code{#f} and prints a message on the current output or
+error port. Characters are output as if the string were output by the
+@code{display} function with the exception of those prefixed by a tilde
+(~). For a detailed description of the @var{format-string} syntax
+please consult a Common LISP format reference manual. For a test suite
+to verify this format implementation load @file{formatst.scm}. Please
+send bug reports to @code{lutzeb@@cs.tu-berlin.de}.
+
+Note: @code{format} is not reentrant, i.e. only one @code{format}-call
+may be executed at a time.
+
+@end defun
+
+@node Format Specification, , Format Interface, Format
+@subsection Format Specification (Format version 3.0)
+
+Please consult a Common LISP format reference manual for a detailed
+description of the format string syntax. For a demonstration of the
+implemented directives see @file{formatst.scm}.@refill
+
+This implementation supports directive parameters and modifiers
+(@code{:} and @code{@@} characters). Multiple parameters must be
+separated by a comma (@code{,}). Parameters can be numerical parameters
+(positive or negative), character parameters (prefixed by a quote
+character (@code{'}), variable parameters (@code{v}), number of rest
+arguments parameter (@code{#}), empty and default parameters. Directive
+characters are case independent. The general form of a directive
+is:@refill
+
+@noindent
+@var{directive} ::= ~@{@var{directive-parameter},@}[:][@@]@var{directive-character}
+
+@noindent
+@var{directive-parameter} ::= [ [-|+]@{0-9@}+ | '@var{character} | v | # ]
+
+
+@subsubsection Implemented CL Format Control Directives
+
+Documentation syntax: Uppercase characters represent the corresponding
+control directive characters. Lowercase characters represent control
+directive parameter descriptions.
+
+@table @asis
+@item @code{~A}
+Any (print as @code{display} does).
+@table @asis
+@item @code{~@@A}
+left pad.
+@item @code{~@var{mincol},@var{colinc},@var{minpad},@var{padchar}A}
+full padding.
+@end table
+@item @code{~S}
+S-expression (print as @code{write} does).
+@table @asis
+@item @code{~@@S}
+left pad.
+@item @code{~@var{mincol},@var{colinc},@var{minpad},@var{padchar}S}
+full padding.
+@end table
+@item @code{~D}
+Decimal.
+@table @asis
+@item @code{~@@D}
+print number sign always.
+@item @code{~:D}
+print comma separated.
+@item @code{~@var{mincol},@var{padchar},@var{commachar}D}
+padding.
+@end table
+@item @code{~X}
+Hexadecimal.
+@table @asis
+@item @code{~@@X}
+print number sign always.
+@item @code{~:X}
+print comma separated.
+@item @code{~@var{mincol},@var{padchar},@var{commachar}X}
+padding.
+@end table
+@item @code{~O}
+Octal.
+@table @asis
+@item @code{~@@O}
+print number sign always.
+@item @code{~:O}
+print comma separated.
+@item @code{~@var{mincol},@var{padchar},@var{commachar}O}
+padding.
+@end table
+@item @code{~B}
+Binary.
+@table @asis
+@item @code{~@@B}
+print number sign always.
+@item @code{~:B}
+print comma separated.
+@item @code{~@var{mincol},@var{padchar},@var{commachar}B}
+padding.
+@end table
+@item @code{~@var{n}R}
+Radix @var{n}.
+@table @asis
+@item @code{~@var{n},@var{mincol},@var{padchar},@var{commachar}R}
+padding.
+@end table
+@item @code{~@@R}
+print a number as a Roman numeral.
+@item @code{~:@@R}
+print a number as an ``old fashioned'' Roman numeral.
+@item @code{~:R}
+print a number as an ordinal English number.
+@item @code{~:@@R}
+print a number as a cardinal English number.
+@item @code{~P}
+Plural.
+@table @asis
+@item @code{~@@P}
+prints @code{y} and @code{ies}.
+@item @code{~:P}
+as @code{~P but jumps 1 argument backward.}
+@item @code{~:@@P}
+as @code{~@@P but jumps 1 argument backward.}
+@end table
+@item @code{~C}
+Character.
+@table @asis
+@item @code{~@@C}
+prints a character as the reader can understand it (i.e. @code{#\} prefixing).
+@item @code{~:C}
+prints a character as emacs does (eg. @code{^C} for ASCII 03).
+@end table
+@item @code{~F}
+Fixed-format floating-point (prints a flonum like @var{mmm.nnn}).
+@table @asis
+@item @code{~@var{width},@var{digits},@var{scale},@var{overflowchar},@var{padchar}F}
+@item @code{~@@F}
+If the number is positive a plus sign is printed.
+@end table
+@item @code{~E}
+Exponential floating-point (prints a flonum like @var{mmm.nnn}@code{E}@var{ee}).
+@table @asis
+@item @code{~@var{width},@var{digits},@var{exponentdigits},@var{scale},@var{overflowchar},@var{padchar},@var{exponentchar}E}
+@item @code{~@@E}
+If the number is positive a plus sign is printed.
+@end table
+@item @code{~G}
+General floating-point (prints a flonum either fixed or exponential).
+@table @asis
+@item @code{~@var{width},@var{digits},@var{exponentdigits},@var{scale},@var{overflowchar},@var{padchar},@var{exponentchar}G}
+@item @code{~@@G}
+If the number is positive a plus sign is printed.
+@end table
+@item @code{~$}
+Dollars floating-point (prints a flonum in fixed with signs separated).
+@table @asis
+@item @code{~@var{digits},@var{scale},@var{width},@var{padchar}$}
+@item @code{~@@$}
+If the number is positive a plus sign is printed.
+@item @code{~:@@$}
+A sign is always printed and appears before the padding.
+@item @code{~:$}
+The sign appears before the padding.
+@end table
+@item @code{~%}
+Newline.
+@table @asis
+@item @code{~@var{n}%}
+print @var{n} newlines.
+@end table
+@item @code{~&}
+print newline if not at the beginning of the output line.
+@table @asis
+@item @code{~@var{n}&}
+prints @code{~&} and then @var{n-1} newlines.
+@end table
+@item @code{~|}
+Page Separator.
+@table @asis
+@item @code{~@var{n}|}
+print @var{n} page separators.
+@end table
+@item @code{~~}
+Tilde.
+@table @asis
+@item @code{~@var{n}~}
+print @var{n} tildes.
+@end table
+@item @code{~}<newline>
+Continuation Line.
+@table @asis
+@item @code{~:}<newline>
+newline is ignored, white space left.
+@item @code{~@@}<newline>
+newline is left, white space ignored.
+@end table
+@item @code{~T}
+Tabulation.
+@table @asis
+@item @code{~@@T}
+relative tabulation.
+@item @code{~@var{colnum,colinc}T}
+full tabulation.
+@end table
+@item @code{~?}
+Indirection (expects indirect arguments as a list).
+@table @asis
+@item @code{~@@?}
+extracts indirect arguments from format arguments.
+@end table
+@item @code{~(@var{str}~)}
+Case conversion (converts by @code{string-downcase}).
+@table @asis
+@item @code{~:(@var{str}~)}
+converts by @code{string-capitalize}.
+@item @code{~@@(@var{str}~)}
+converts by @code{string-capitalize-first}.
+@item @code{~:@@(@var{str}~)}
+converts by @code{string-upcase}.
+@end table
+@item @code{~*}
+Argument Jumping (jumps 1 argument forward).
+@table @asis
+@item @code{~@var{n}*}
+jumps @var{n} arguments forward.
+@item @code{~:*}
+jumps 1 argument backward.
+@item @code{~@var{n}:*}
+jumps @var{n} arguments backward.
+@item @code{~@@*}
+jumps to the 0th argument.
+@item @code{~@var{n}@@*}
+jumps to the @var{n}th argument (beginning from 0)
+@end table
+@item @code{~[@var{str0}~;@var{str1}~;...~;@var{strn}~]}
+Conditional Expression (numerical clause conditional).
+@table @asis
+@item @code{~@var{n}[}
+take argument from @var{n}.
+@item @code{~@@[}
+true test conditional.
+@item @code{~:[}
+if-else-then conditional.
+@item @code{~;}
+clause separator.
+@item @code{~:;}
+default clause follows.
+@end table
+@item @code{~@{@var{str}~@}}
+Iteration (args come from the next argument (a list)).
+@table @asis
+@item @code{~@var{n}@{}
+at most @var{n} iterations.
+@item @code{~:@{}
+args from next arg (a list of lists).
+@item @code{~@@@{}
+args from the rest of arguments.
+@item @code{~:@@@{}
+args from the rest args (lists).
+@end table
+@item @code{~^}
+Up and out.
+@table @asis
+@item @code{~@var{n}^}
+aborts if @var{n} = 0
+@item @code{~@var{n},@var{m}^}
+aborts if @var{n} = @var{m}
+@item @code{~@var{n},@var{m},@var{k}^}
+aborts if @var{n} <= @var{m} <= @var{k}
+@end table
+@end table
+
+
+@subsubsection Not Implemented CL Format Control Directives
+
+@table @asis
+@item @code{~:A}
+print @code{#f} as an empty list (see below).
+@item @code{~:S}
+print @code{#f} as an empty list (see below).
+@item @code{~<~>}
+Justification.
+@item @code{~:^}
+(sorry I don't understand its semantics completely)
+@end table
+
+
+@subsubsection Extended, Replaced and Additional Control Directives
+
+@table @asis
+@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}D}
+@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}X}
+@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}O}
+@item @code{~@var{mincol},@var{padchar},@var{commachar},@var{commawidth}B}
+@item @code{~@var{n},@var{mincol},@var{padchar},@var{commachar},@var{commawidth}R}
+@var{commawidth} is the number of characters between two comma characters.
+@end table
+
+@table @asis
+@item @code{~I}
+print an R5RS complex number as @code{~F~@@Fi} with passed parameters for
+@code{~F}.
+@item @code{~Y}
+Pretty print formatting of an argument for scheme code lists.
+@item @code{~K}
+Same as @code{~?.}
+@item @code{~!}
+Flushes the output if format @var{destination} is a port.
+@item @code{~_}
+Print a @code{#\space} character
+@table @asis
+@item @code{~@var{n}_}
+print @var{n} @code{#\space} characters.
+@end table
+@item @code{~/}
+Print a @code{#\tab} character
+@table @asis
+@item @code{~@var{n}/}
+print @var{n} @code{#\tab} characters.
+@end table
+@item @code{~@var{n}C}
+Takes @var{n} as an integer representation for a character. No arguments
+are consumed. @var{n} is converted to a character by
+@code{integer->char}. @var{n} must be a positive decimal number.@refill
+@item @code{~:S}
+Print out readproof. Prints out internal objects represented as
+@code{#<...>} as strings @code{"#<...>"} so that the format output can always
+be processed by @code{read}.
+@refill
+@item @code{~:A}
+Print out readproof. Prints out internal objects represented as
+@code{#<...>} as strings @code{"#<...>"} so that the format output can always
+be processed by @code{read}.
+@item @code{~Q}
+Prints information and a copyright notice on the format implementation.
+@table @asis
+@item @code{~:Q}
+prints format version.
+@end table
+@refill
+@item @code{~F, ~E, ~G, ~$}
+may also print number strings, i.e. passing a number as a string and
+format it accordingly.
+@end table
+
+@subsubsection Configuration Variables
+
+Format has some configuration variables at the beginning of
+@file{format.scm} to suit the systems and users needs. There should be
+no modification necessary for the configuration that comes with SLIB.
+If modification is desired the variable should be set after the format
+code is loaded. Format detects automatically if the running scheme
+system implements floating point numbers and complex numbers.
+
+@table @asis
+
+@item @var{format:symbol-case-conv}
+Symbols are converted by @code{symbol->string} so the case type of the
+printed symbols is implementation dependent.
+@code{format:symbol-case-conv} is a one arg closure which is either
+@code{#f} (no conversion), @code{string-upcase}, @code{string-downcase}
+or @code{string-capitalize}. (default @code{#f})
+
+@item @var{format:iobj-case-conv}
+As @var{format:symbol-case-conv} but applies for the representation of
+implementation internal objects. (default @code{#f})
+
+@item @var{format:expch}
+The character prefixing the exponent value in @code{~E} printing. (default
+@code{#\E})
+
+@end table
+
+@subsubsection Compatibility With Other Format Implementations
+
+@table @asis
+@item SLIB format 2.x:
+See @file{format.doc}.
+
+@item SLIB format 1.4:
+Downward compatible except for padding support and @code{~A}, @code{~S},
+@code{~P}, @code{~X} uppercase printing. SLIB format 1.4 uses C-style
+@code{printf} padding support which is completely replaced by the CL
+@code{format} padding style.
+
+@item MIT C-Scheme 7.1:
+Downward compatible except for @code{~}, which is not documented
+(ignores all characters inside the format string up to a newline
+character). (7.1 implements @code{~a}, @code{~s},
+~@var{newline}, @code{~~}, @code{~%}, numerical and variable
+parameters and @code{:/@@} modifiers in the CL sense).@refill
+
+@item Elk 1.5/2.0:
+Downward compatible except for @code{~A} and @code{~S} which print in
+uppercase. (Elk implements @code{~a}, @code{~s}, @code{~~}, and
+@code{~%} (no directive parameters or modifiers)).@refill
+
+@item Scheme->C 01nov91:
+Downward compatible except for an optional destination parameter: S2C
+accepts a format call without a destination which returns a formatted
+string. This is equivalent to a #f destination in S2C. (S2C implements
+@code{~a}, @code{~s}, @code{~c}, @code{~%}, and @code{~~} (no directive
+parameters or modifiers)).@refill
+
+@end table
+
+This implementation of format is solely useful in the SLIB context
+because it requires other components provided by SLIB.@refill