code:
\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, 2006 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, 2006 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.2 2006-04-16 23:05:07 kryde 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


code:
@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

license: mit


code:
@node Guile and SLIB
@chapter Guile and SLIB


code:
@menu
Preliminary

* Introduction::
* Using Guile::

@bye

>You can actually put any English text to break up the menu, so you
>could put the "Part n" headings in it.

Introduction
    --- Explains Guile's goals, and gives brief examples of how to use
        Guile interactively (show off repl), as a script interpreter,
        and as an embedded interpreter.

Part I: Guile Scheme
    R4RS Scheme as a Starting Point
	--- Here we refer to R4RS, and explain that we're only
	    describing differences.
    Block comments and interpreter triggers
    Symbol case
    Keywords
    Exceptions
    Modules
	--- the preceeding three come first, because we need them
	    in order to explain the behavior of some things later
    Exception Handling
        --- mention that repls usually establish default exception handlers
    Dynamic Wind
    Records
    Structures
    Arrays
    Binary Numeric Operations
    Shared and Read-Only Strings
    Object Properties
    Association Lists and Hash Tables
        (Dictionaries In General)
        association lists
        hash tables (Hash Values)
    Input/Output ports
	file ports
	soft ports
	string ports
	extended I/O (fseek; line read/write)
    Garbage Collection
    Threads and Dynamic Roots
    Reflection
        eval
        Tag Values
    Weak references
    Regular Expressions
    SLIB
    POSIX system calls and networking
	--- I think people will generally know whether they're looking
	    for a system call or not, so this should be an okay category.
	conventions (includes error handling)
	ports vs. file descriptors
	file system (mknod goes here, no?)
	user database
	time (includes gettimeofday or whatever, strftime, strptime)
	processes
	terminals and pseudo-terminals
	pipes
	networking (includes databases, address conversion, and sockets)
	system identification (uname)
	locales (setlocale)
	--- Note that there is no more 'misc'.  It's better to have
	    small sections than unhelpful names.
    SCSH
	--- includes info on how to get SCSH features (open this
            module), but mostly just a pointer to the SCSH manual.
            This should not be under POSIX.  SCSH includes plenty of
	    high-level stuff for starting processes and string
	    processing.  SCSH is not a subset of POSIX, nor the
            reverse.
    Tcl/Tk interface
    Module internals
        first-class variables
	first-class modules
    internal debugging interface
	--- The name of this chapter needs to clearly distinguish it
	    from the appendix describing the debugger UI.  The intro
	    should have a pointer to the UI appendix.

Part II: Using Scheme with C --- a Portable Interface
    --- We cover gh in a completely separate section.  Why?  I admit
        I'm on shaky ground, but here's my reasoning: People who want
        to write portable C code need to restrict themselves to only
        using GH, and GH's semantics are (necessarily) well-defined
        without reference to Guile's particulars.  This makes life
        more difficult for folks who just prefer to use the GH
        interface when they can, but I really think the SCM interface
        is not so bad, once you're used to it.  A *lot* of GH
        functions are just wrappers for SCM functions.
    --- We cover repls here too, since GH has repl functions.

Part III: Using Scheme with C --- Guile's Interface
    Scheme data representation
    Relationship between Scheme and C functions
        --- this is where we explain that all the functions marked as
	    "Primitive Functions" are also accessible from C, and how
	    to derive the C interface given the Scheme interface, when
	    we don't spell it out.
    ... I think there's other stuff needed here ...
    I/O internals
    linking Guile with your code
	--- Mark's "Tools to automate adding libraries" is not a
            well-defined concept.  I think this is closer to what we
            want to cover for now.
    snarfing

Appendices:
    Obtaining and Installing Guile
    Invoking Guile
        --- mentions read-eval-print loops
	--- both the SCSH and GAWK manuals relegate invocation details
            to an appendix.  We can give examples in the introduction.
    debugger user interface
	--- The title and introduction of this appendix need to
            distinguish this clearly from the chapter on the internal
            debugging interface.

Indices:
	--- At the top of the function/variable index, remind people
            to look for functions under their Scheme names as well as
            their C names.


code:
@node Libguile overview
@chapter Libguile overview
@cindex libguile - overview

Extension languages, like Guile, Python and Tcl, can be embedded into a
C program, @footnote{Or a C++ or Fortran or Pascal program if you want.}
and thus allow the user to @emph{extend} the C program.

The way this is done is by providing a C language library with a well
defined interface.  The interface consists of a set of public and
documented C-callable routines that offer the full interpreter
functionality, and allow the conversion of data between C and the
extension language.

@menu
* An example of libguile functionality::
* What can be done with libguile::
* Schizofrenia -- two APIs::
@end menu

@node An example of libguile functionality
@section An example of libguile functionality

[Two examples: using strings and using data conversion.]

@node What can be done with libguile
@section What can be done with libguile

@node Schizofrenia -- two APIs
@section Schizofrenia -- two APIs


code:
@node Tools to automate adding libraries
@chapter Tools to automate adding libraries

You want to ...

The chapters @ref{Libguile -- high level interface} and @ref{Libguile --
SCM interface} showed how to make C libraries available from Scheme.
Here I will describe some automated tools that the Guile team has made
available.  Some have been written especially for Guile (the Guile Magic
Snarfer), and some are also in use with other languages (Python, Perl,
...)

@menu
* By hand with gh_::
* By hand with Guile Magic Snarfer::
* Automatically using libtool::
* Automatically using SWIG::
@end menu

@node By hand with gh_
@section By hand with gh_

@node By hand with Guile Magic Snarfer
@section By hand with Guile Magic Snarfer

When writing C code for use with Guile, you typically define a set of C
functions, and then make some of them visible to the Scheme world by
calling the @code{scm_make_gsubr} function; a C functions published in
this way is called a @dfn{subr}.  If you have many subrs to publish, it
can sometimes be annoying to keep the list of calls to
@code{scm_make_gsubr} in sync with the list of function definitions.
Frequently, a programmer will define a new subr in C, recompile his
application, and then discover that the Scheme interpreter cannot see
the subr, because he forgot to call @code{scm_make_gsubr}.

Guile provides the @code{guile-snarf} command to manage this problem.
Using this tool, you can keep all the information needed to define the
subr alongside the function definition itself; @code{guile-snarf} will
extract this information from your source code, and automatically
generate a file of calls to @code{scm_make_gsubr} which you can
@code{#include} into an initialization function.  (The command name
comes from the verb ``to snarf'', here meaning ``to unceremoniously
extract information from a somewhat unwilling source.'')

@menu
* How guile-snarf works::       Using the @code{guile-snarf} command.
* Macros guile-snarf recognizes::  How to mark up code for @code{guile-snarf}.
@end menu

@node How guile-snarf works
@subsection How @code{guile-snarf} works

For example, here is how you might define a new subr called
@code{clear-image}, implemented by the C function @code{clear_image}:

@example
@group
#include <libguile.h>

@dots{}

SCM_PROC (s_clear_image, "clear-image", 1, 0, 0, clear_image);

SCM
clear_image (SCM image_smob)
@{
  @dots{}
@}

@dots{}

void
init_image_type ()
@{
#include "image-type.x"
@}
@end group
@end example

The @code{SCM_PROC} declaration says that the C function
@code{clear_image} implements a Scheme subr called @code{clear-image},
which takes one required argument, no optional arguments, and no tail
argument.  @code{SCM_PROC} also declares a static array of characters
named @code{s_clear_image}, initialized to the string
@code{"clear-image"}.  The body of @code{clear_image} may use the array
in error messages, instead of writing out the literal string; this may
save string space on some systems.

Assuming the text above lives in a file named @file{image-type.c}, you will
need to execute the following command to compile this file:
@example
guile-snarf image-type.c > image-type.x
@end example
@noindent This scans @file{image-type.c} for @code{SCM_PROC}
declarations, and sends the following output to the file
@file{image-type.x}:
@example
scm_make_gsubr (s_clear_image, 1, 0, 0, clear_image);
@end example
When compiled normally, @code{SCM_PROC} is a macro which expands to a
declaration of the @code{s_clear_image} string.

In other words, @code{guile-snarf} scans source code looking for uses of
the @code{SCM_PROC} macro, and generates C code to define the
appropriate subrs.  You need to provide all the same information you
would if you were using @code{scm_make_gsubr} yourself, but you can
place the information near the function definition itself, so it is less
likely to become incorrect or out-of-date.

If you have many files that @code{guile-snarf} must process, you should
consider using a rule like the following in your Makefile:
@example
.SUFFIXES: .x
.c.x:
	./guile-snarf $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@
@end example
This tells make to run @code{guile-snarf} to produce each needed
@file{.x} file from the corresponding @file{.c} file.

@code{guile-snarf} passes all its command-line arguments directly to the
C preprocessor, which it uses to extract the information it needs from
the source code. this means you can pass normal compilation flags to
@code{guile-snarf} to define preprocessor symbols, add header file
directories, and so on.

@node Macros guile-snarf recognizes
@subsection Macros @code{guile-snarf} recognizes

Here are the macros you can use in your source code from which
@code{guile-snarf} can construct initialization code:

@defmac SCM_PROC (@var{namestr}, @var{name}, @var{req}, @var{opt}, @var{tail}, @var{c_func})
Declare a new Scheme primitive function, or @dfn{subr}.  The new subr
will be named @var{name} in Scheme code, and be implemented by the C
function @var{c_func}.  The subr will take @var{req} required arguments
and @var{opt} optional arguments.  If @var{tail} is non-zero, the
function will accept any remaining arguments as a list.

Use this macro outside all function bodies, preferably above the
definition of @var{c_func} itself.  When compiled, the @code{SCM_PROC}
declaration will expand to a definition for the @var{namestr} array,
initialized to @var{name}.  The @code{guile-snarf} command uses this
declaration to automatically generate initialization code to create the
subr and bind it in the top-level environment.  @xref{How guile-snarf
works}, for more info.

@xref{Subrs}, for details on argument passing and how to write
@var{c_func}.
@end defmac

@defmac SCM_GLOBAL (@var{var}, @var{scheme_name})
Declare a global Scheme variable named @var{scheme_name}, and a static C
variable named @var{var} to point to it.  The value of the Scheme
variable lives in the @sc{cdr} of the cell @var{var} points to.
Initialize the variable to @code{#f}.

Use this macro outside all function bodies.  When compiled, the
@code{SCM_GLOBAL} macro will expand to a definition for the variable
@var{var}, initialized to an innocuous value.  The @code{guile-snarf}
command will use this declaration to automatically generate code to
create a global variable named @var{scheme_name}, and store a pointer to
its cell in @var{var}.
@end defmac

@defmac SCM_CONST_LONG (@var{var}, @var{scheme_name}, @var{value})
Like @code{SCM_GLOBAL}, but initialize the variable to @var{value},
which must be an integer.
@end defmac

@defmac SCM_SYMBOL (@var{var}, @var{name})
Declare a C variable of type @code{SCM} named @var{var}, and initialize
it to the Scheme symbol object whose name is @var{name}.

Use this macro outside all function bodies.  When compiled, the
@code{SCM_SYMBOL} macro will expand to a definition for the variable
@var{var}, initialized to an innocuous value.  The @code{guile-snarf}
command will use this declaration to automatically generate code to
create a symbol named @var{name}, and store it in @var{var}.
@end defmac

@node Automatically using libtool
@section Automatically using libtool

@node Automatically using SWIG
@section Automatically using SWIG


code:
@node Adding types to Guile
@chapter Adding types to Guile


code:
@node Introduction
@chapter Introduction

Guile is an interpreter for Scheme, a clean, economical programming
language in the Lisp family.  You can invoke Guile from the shell to
evaluate Scheme expressions interactively, or use it as an interpreter
for script files.  However, Guile is also packaged as a library, to be
embedded as an extension language into other applications.  The
application can supplement the base language with special-purpose
functions and datatypes, allowing the user to customize and extend it by
writing Scheme code.

In its simplest form, Guile is an ordinary interpreter.  The
@code{guile} program can read and evaluate Scheme expressions entered
from the terminal.  Here is a sample interaction between Guile and a
user; the user's input appears after the @code{$} and @code{guile>}
prompts:

@example
$ guile
guile> (+ 1 2 3)                ; add some numbers
6
guile> (define (factorial n)    ; define a function
         (if (zero? n) 1 (* n (factorial (- n 1)))))
guile> (factorial 20)
2432902008176640000
guile> (getpwnam "jimb")        ; find my entry in /etc/passwd
#("jimb" ".0krIpK2VqNbU" 4008 10 "Jim Blandy" "/u/jimb"
  "/usr/local/bin/bash")
guile> @kbd{C-d}
$
@end example

Guile can also interpret script files.  For example, here is a Guile script
containing a script which displays the

application can
supplement the base language with its own functions, datatypes and
syntax, allowing the user to extend and

 Guile interpret

.  An
application the Guile interpreter to allow

, allowing
applications to incorporate the Scheme interpreter for customization

[[interactive]]
[[script interpreter]]
[[embedded]]

[[other languages]]
The concept of an extension language library does not originate with
Guile.  However, Guile is the first to offer users a choice of languages
to program in.

Guile currently supports Scheme and Ctax , and we expect to support Emacs Lisp in the near future.

Scheme is powerful enough that other languages can be
conveniently translated into it,

However, unlike other extension packages, Guile gives users a choice of
languages to program in.  Guile can

In this sense, Guile resembles the Tcl and Python packages, providing
both an ordinary interpreter and an extension language library.
However, unlike those packages, Guile supports more than one programming
language.

; users can
write Scheme code to control and customize applications which
incorporate Guile

, adding their own functions,
datatypes, and syntax, to allow the user to programm

link it into your own programs to make them

Guile is a library containing an interpreter for Scheme, a complete but
economical programming language, which the developer can customize to
suit the application at hand by adding new functions, data types, and
control structures.  These may be implemented in C, and then
``exported'' for use by the interpreted code.  Because Guile already
provides a full-featured interpreter, the developer need not neglect the
language's design in order to concentrate on code relevant to the task.
In this way, Guile provides a framework for the construction of
domain-specific languages.

Guile provides first-class functions, a rich set of data types,
exception handling, a module system, and a powerful macro facility.
Guile also supports dynamic linking and direct access to Unix system
calls.  Releases in the near future will support a source-level
debugger and bindings for the Tk user interface toolkit.

Guile is a framework for writing applications controlled by specialized
languages.  In its simplest form, Guile is an interpreter for Scheme, a
clean, economical programming language in the Lisp family.  However,
Guile is packaged as a library, allowing applications to link against it
and use Scheme as their extension language.  The application can add
primitive functions to the language, implement new data types, and even
adjust the language's syntax.

[the introduction is probably not what Jim has in mind; I just took the
one I had in earlier, since the file had the same name intro.texi]

Guile is an implementation of the Scheme programming language, but, like
other modern implementations of Scheme, it adds many features that the
community of Scheme programmers considers necessary for an ``industrial
strength'' language.

Examples of extensions to Scheme are the module system
(@pxref{Modules}), the Unix system programming tools (@pxref{POSIX
system calls and networking} and @pxref{The Scheme shell (scsh)}), an
interface to @emph{libtool} to make it easier to add C libraries as
primitives (@pxref{Linking Guile with your code}), and (FIXME add more).

On top of these extensions, which many other Scheme implementations
provide, Guile also offers the possibility of writing routines in other
languages and running them simultaneously with Scheme.  The desire to
implement other languages (in particular Emacs Lisp) on top of Scheme is
responsible for Guile's only deviation from the R4RS @footnote{R4RS is
the Revised^4 Report on the Algorithmic Language Scheme, the closest
thing to a standard Scheme specification today} Scheme standard
(@cite{r4rs}): Guile is case sensitive, whereas ``standard'' Scheme is
not.

But even more fundamentally, Guile is meant to be an @emph{embeddable}
Scheme interpreter.  This means that a lot of work has gone into
packaging the interpreter as a C library (@pxref{A Portable C to Scheme Interface} and @pxref{Scheme data representation}).

This reference manual is mainly driven by the need to document all the
features that go beyond standard Scheme.

@menu
* Getting started::
* Guile feature list::
* What you need to use Guile::
* Roadmap to the Manual::
* Motivation for Guile::
* History of Guile::
@end menu

@node Getting started
@section Getting started

We assume that you know how to program in Scheme, although we do not
assume advanced knowledge.  If you don't know Scheme, there are many
good books on Scheme at all levels, and the Guile Tutorial might give
you a good enough feel for the language.  We also assume that you know
how to program in C, since there will be many examples of how to program
in C using Guile as a library.

Many diverse topics from the world of Unix hacking will be covered here,
such as shared libraries, socket programming, garbage collection, and so
forth.  If at any time you feel you don't have enough background on a
given topic, just go up a level or two in the manual, and you will find
that the chapter begins with a few paragraphs that introduce the topic.
If you are still lost, read through the Guile tutorial and then come
back to this reference manual.

To run the core Guile interpreter and extension library you need no more
than a basically configured GNU/Unix system and the Guile sources.  You
should download and install the Guile sources (@pxref{Obtaining and
Installing Guile}).

@node Guile feature list
@section Guile feature list

In a reductionist view, Guile could be regarded as:
@itemize @bullet
@item
An R4RS-compliant Scheme interpreter.

@item
Some Scheme features that go beyond the R4RS standard, notably a module
system, exception handling primitives and an interface to Aubrey
Jaffer's SLIB.

@item
A symbolic debugger for Scheme, and gdb extensions to facilitate
debugging libguile programs.

@item
An embeddable version of the same interpreter, called @emph{libguile}.

@item
A portable high level API on top of libguile (the @code{gh_} interface).

@item
A collection of bundled C libraries with a Guile API.  As we write, this
list includes:

@table @strong
@item Rx
a regular expression library.

@item Unix
a low-level interface to the POSIX system calls, socket library
and other Unix system services.

@item Tk
an interface to John Ousterhout's Tk toolkit.

@end table

@item
A set of tools for implementing other languages @emph{on top of Scheme},
and an example implementation of a language called @emph{Ctax}.

@end itemize

@node What you need to use Guile
@section What you need to use Guile

@node Roadmap to the Manual
@section Roadmap to the Manual

@node Motivation for Guile
@section Motivation for Guile

@node History of Guile
@section History of Guile

@page
@node Using Guile
@chapter Using Guile

[I think that this might go in the appendix in Jim's view of the manual]

@page
@node Invoking Guile
@appendix Invoking Guile
        --- mentions read-eval-print loops
	--- both the SCSH and GAWK manuals relegate invocation details
            to an appendix.  We can give examples in the introduction.

@table @samp
@item -h
@itemx --help
Display a helpful message.
@item -v
@item --version
Display the current version.
@item --emacs
To be used for emacs editing support.
@item -s @var{file}
Process @var{file} as a script then quit.  This is a terminating option:
any further command line arguments can be accessed by the script using
the @code{(program-arguments)} procedure.

An executable script can start with the following:

@smallexample
#!/usr/bin/guile -s
!#
@end smallexample

Note the @code{!#} token on the second line.  It is very important
to include this token when writing Guile scripts.  Guile and SCSH,
the Scheme shell, share the convention that @code{#!}  and
@code{!#} may be used to mark block comments (@pxref{Block
comments and interpreter triggers}).  If the closing @code{!#}
token is not included, then Guile will consider the block comment
to be unclosed, and the script will probably not compile
correctly.

It is also important to include the @samp{-s} option at the
beginning of the Guile script, so that Guile knows not to behave
in an interactive fashion.

@end table


code:
@node Examples of adding libraries
@chapter Examples of adding libraries

Should contain examples of brute-force gh_, Guile magic snarfer,
libtool, SWIG on a dummy API, followed by some real examples of how
libraries are added.


code:
@node Guile Scheme concepts
@chapter Guile Scheme concepts

Most Scheme implementations go beyond what is specified in the R4RS
document @footnote{Remember?  R4RS is the Revised^4 report on the
Algorithmic Language Scheme}, mostly because R4RS does not give
specifications (or even recommendations) regarding some issues that are
quite important in practical programming.

Here is a list of how Guile implements some of these much-needed Scheme
extensions; other Scheme implementations do so quite similarly.

@menu
* Scheme slang::
* Read-eval-print loops::
* Extra data types::
* Miscellaneous features::
@end menu

@node Scheme slang
@section Scheme slang
@cindex slang

Even if you read some of the nice books on Scheme, or the R4RS report,
you might not find some of the terms frequently used by Scheme hackers,
both in the manual and in the @url{news:comp.lang.scheme} newsgroup.

Here is a glossary of some of the terms that make Scheme beginners and
intermediate users say ``huh?''

@table @strong
@item thunk
@cindex thunk
A Scheme procedure that takes no arguments.  In this example,
@code{thunk} and @code{another-thunk} are both thunks:
@lisp
(define (thunk)
  (display "Dude, I'm a thunk!")
  (newline))
(define another-thunk
  (lambda ()
    (display "Me too!\n")
    (newline)))
@end lisp

@item closure
@cindex closure
A closure is a procedure.  However, the term emphasizes the fact that a
Scheme procedure remembers (or @dfn{closes over}) the variables that
were visible when the @code{lambda} expression was
evaluated.

In the example below, we might refer to @code{q} as a closure, because
it has closed over the value of @code{x}:
@lisp
(define p
  (lambda (x)
    (lambda (y)
      (+ x y))))
(define q (p 5.7))

(q 10)
@result{} 15.7
@end lisp

However, strictly speaking, every Scheme procedure is really a closure,
since it closes over the top-level environment.

@item alist
@itemx association list

@item plist
@itemx property list

@end table

@node Read-eval-print loops
@section Read-eval-print loops
@cindex Read-eval-print loop
@cindex REPL

To explicitly mention the Scheme read-eval-print loop (REPL) seems weird
because we are all accustomed to firing up an interpreter and having it
read and execute commands.

But the REPL is not specified in R4RS; rather, it is proposed by the
Scheme Bible @cite{Structure and Interpretation of Computer Programs}
(also known as @emph{SICP}), and implemented in some form in all Scheme
interpreters.
@cindex Structure and Interpretation of Computer Programs
@cindex SICP

[FIXME: Someone needs to tell me what needs to be said about Guile's
REPL.]

@node Extra data types
@section Extra data types

The fundamental Scheme data types specified in R4RS are @emph{numbers}
(both exact and inexact), @emph{characters}, @emph{strings},
@emph{symbols}, @emph{vectors}, @emph{pairs} and @emph{lists} [FIXME: is
this complete?].

Many Scheme interpreters offer more types, and Guile is no exception.
Guile is based on Aubrey Jaffer's SCM interpreter, and thus inherits
@emph{uniform arrays}, [FIXME: any others?  How about records?].

On top of that, Guile allows you to add extra types, but that is covered
in @ref{Adding types to Guile}.  Here I will simply document all the
extra Scheme types shipped with Guile.

@menu
* Conventional arrays::
* Uniform arrays::
* Bit vectors::
* Complex numbers::
@end menu

@node Conventional arrays
@subsection Conventional arrays

@node Uniform arrays
@subsection Uniform arrays
@cindex arrays - uniform

The motivation for uniform arrays in Scheme is performance.  A vector
provides a performance increase over lists when you want a fixed-size
indexable list.  But the elements in a vector can be of different types,
and this makes for larger storage requirements and slightly lower
performance.

A uniform array is similar to a vector, but all elements have to be of
the same type.

arrays, uniform arrays, bit vectors:

@deffn procedure array-fill ra fill
@end deffn
@deffn procedure serial-array-copy! src dst
@end deffn
@deffn procedure serial-array-map ra0 proc [lra]
@end deffn
@deffn procedure array-map ra0 proc [lra]
@end deffn
@deffn procedure array-for-each proc ra0 [lra]
@end deffn
@deffn procedure array-index-map! ra proc
@end deffn
@deffn procedure array-copy! src dst
@end deffn
@deffn procedure array-copy! src dst
@end deffn
@deffn procedure array-copy! src dst
@end deffn
@deffn procedure array-copy! src dst
@end deffn
@deffn procedure array-copy! src dst
@end deffn
@deffn procedure array? ra [prot]
@end deffn
@deffn procedure array-rank ra
@end deffn
@deffn procedure array-dimensions ra
@end deffn
@deffn procedure dimensions->uniform-array dims prot fill ...
@end deffn
@deffn procedure make-shared-array ra mapfunc dims ...
@end deffn
@deffn procedure transpose-array arg ...
@end deffn
@deffn procedure enclose-array axes ...
@end deffn
@deffn procedure array-in-bounds? arg ...
@end deffn
@deffn procedure array-ref ra arg ..
@end deffn
@deffn procedure uniform-vector-ref vec pos
@end deffn
@deffn procedure array-set! ra obj arg ...
@end deffn
@deffn procedure uniform-array-set1! ua obj arg
@end deffn
@deffn procedure array-contents ra [strict]
@end deffn
@deffn procedure uniform-array-read! ra [port-or-fd] [start] [end]
@end deffn
@deffn procedure uniform-array-write! ra [port-or-fd] [start] [end]
@end deffn
@deffn procedure bit-count item seq
@end deffn
@deffn procedure bit-position item v k
@end deffn
@deffn procedure bit-set! v kv obj
@end deffn
@deffn procedure bit-count* v kv obj
@end deffn
@deffn procedure bit-invert v
@end deffn
@deffn procedure array->list ra
@end deffn
@deffn procedure list->uniform-array ndim prot list
@end deffn
@deffn procedure array-prototype ra
@end deffn

Unform arrays can be written and read, but @code{read} won't recognize
them unless the optional @code{read-sharp} parameter is supplied,
e.g,
@smalllisp
(read port #t read-sharp)
@end smalllisp

where @code{read-sharp} is the default procedure for parsing extended
sharp notations.

Reading an array is not very efficient at present, since it's implemented
by reading a list and converting the list to an array.

@c FIXME: must use @deftp, but its generation of TeX code is buggy.
@c Must fix it when TeXinfo gets fixed.
@deftp {Scheme type} {uniform array}

@end deftp

@node Bit vectors
@subsection Bit vectors

@node Complex numbers
@subsection Complex numbers

@c FIXME: must use @deftp, but its generation of TeX code is buggy.
@c Must fix it when TeXinfo gets fixed.
@deftp {Scheme type} complex
Standard complex numbers.
@end deftp

@node Miscellaneous features
@section Miscellaneous features

@defun defined? symbol
Returns @code{#t} if a symbol is bound to a value, @code{#f} otherwise.
This kind of procedure is not specified in R4RS because @c FIXME: finish
this thought
@end defun

@defun object-properties OBJ
and so forth
@end defun


code:
@node Libguile -- SCM interface
@chapter Libguile -- SCM interface


code:
@node Strings
@chapter Facilities for string manipulation

@deffn procedure string? string
@end deffn
@deffn procedure read-only-string? string
@end deffn
@deffn procedure list->string list
@end deffn
@deffn procedure make-string length [char]
@end deffn
@deffn procedure string-length string
@end deffn
@deffn procedure string-ref string [index]
@end deffn
@deffn procedure string-set! string index char
@end deffn
@deffn procedure substring string start [end]
@end deffn
@deffn procedure string-append arg ...
@end deffn
@deffn procedure make-shared-substring string [from] [to]
@end deffn
@deffn procedure string-set! string index char
@end deffn
@deffn procedure string-index string char [from] [to]
@end deffn
@deffn procedure string-rindex string char [from] [to]
@end deffn
@deffn procedure substring-move-left! string1 start1 [end1] [string2] [start2]
@end deffn
@deffn procedure substring-move-right! string1 start1 [end1] [string2] [start2]
@end deffn
@deffn procedure substring-fill! string start [end] [fill]
@end deffn
@deffn procedure string-null? string
@end deffn
@deffn procedure string->list string
@end deffn
@deffn procedure string-copy string
@end deffn
@deffn procedure string-upcase! string
@end deffn
@deffn procedure string-downcase! string
@end deffn


code:
@node Tk interface
@chapter Tk interface

For now Guile has no well-specified Tk interface.  It is an important part
of Guile, though, and will be documented here when it is written.


code:
@node Other Unix
@chapter Other Unix-specific facilities

@menu
* Expect::              Expect, for pattern matching from a port.
@end menu

@node Expect
@section Expect: Pattern Matching from a Port

@code{expect} is a macro for selecting actions based on the output from
a port.  The name comes from a tool of similar functionality by Don Libes.
Actions can be taken when a particular string is matched, when a timeout
occurs, or when end-of-file is seen on the port.  The @code{expect} macro
is described below; @code{expect-strings} is a front-end to @code{expect}
based on regexec @xref{Regular expressions}.

Using these macros requires for now:
@smalllisp
(load-from-path "ice-9/expect")
@end smalllisp

@defun expect-strings clause @dots{}
By default, @code{expect-strings} will read from the current input port.
The first term in each clause consists of an expression evaluating to
a string pattern (regular expression).  As characters
are read one-by-one from the port, they are accumulated in a buffer string
which is matched against each of the patterns.  When a
pattern matches, the remaining expression(s) in
the clause are evaluated and the value of the last is returned.  For example:

@smalllisp
(with-input-from-file "/etc/passwd"
  (lambda ()
    (expect-strings
      ("^nobody" (display "Got a nobody user.\n")
                 (display "That's no problem.\n"))
      ("^daemon" (display "Got a daemon user.\n")))))
@end smalllisp

The regular expression is compiled with the @code{REG_NEWLINE} flag, so
that the @code{^} and @code{$} anchors will match at any newline, not
just at the start
and end of the string.

There are two other ways to write a clause:

The expression(s) to evaluate on a match
can be omitted, in which case the result of the match
(converted to strings, as obtained from regexec with @var{match-pick}
set to @code{""}) will be returned if the pattern matches.

The symbol @code{=>} can be used to indicate that there is a single
expression to evaluate on a match, which must be a
procedure which will accept the result of a successful match (converted
to strings, as obtained from regexec with @var{match-pick} set to
@code{""}).  E.g.,

@smalllisp
("^daemon" => write)
("^d\\(aemon\\)" => (lambda args (map write args)))
("^da\\(em\\)on" => (lambda (all sub)
                         (write all)
                         (write sub)))
@end smalllisp

The order of the substrings corresponds to the order in which the
opening brackets occur in the regular expression.

A number of variables can be used to control the behaviour
of @code{expect} (and @code{expect-strings}).
By default they are all bound at the top level to
the value @code{#f}, which produces the default behaviour.
They can be redefined at the
top level or locally bound in a form enclosing the @code{expect} expression.

@table @code
@item expect-port
A port to read characters from, instead of the current input port.
@item expect-timeout
@code{expect} will terminate after this number of
seconds, returning @code{#f} or the value returned by
@code{expect-timeout-proc}.
@item expect-timeout-proc
A procedure called if timeout occurs.  The procedure takes a single argument:
the accumulated string.
@item expect-eof-proc
A procedure called if end-of-file is detected on the input port.  The
procedure takes a single argument: the accumulated string.
@item expect-char-proc
A procedure to be called every time a character is read from the
port.  The procedure takes a single argument: the character which was read.
@end table

Here's an example using all of the variables:

@smalllisp
(let ((expect-port (open-input-file "/etc/passwd"))
      (expect-timeout 1)
      (expect-timeout-proc
        (lambda (s) (display "Times up!\n")))
      (expect-eof-proc
        (lambda (s) (display "Reached the end of the file!\n")))
      (expect-char-proc display))
   (expect-strings
     ("^nobody"  (display "Got a nobody user\n"))))
@end smalllisp
@end defun

@defun expect clause @dots{}
@code{expect} is used in the same way as @code{expect-strings},
but tests are specified not as patterns, but as procedures.  The
procedures are called in turn after each character is read from the
port, with the value of the accumulated string as the argument.  The
test is successful if the procedure returns a non-false value.

If the @code{=>} syntax is used, then if the test succeeds it must return
a list containing the arguments to be provided to the corresponding
expression.

In the following example, a string will only be matched at the beginning
of the file:
@smalllisp
(let ((expect-port (open-input-file "/etc/passwd")))
  (expect
     ((lambda (s) (string=? s "fnord!"))
        (display "Got a nobody user!\n"))))
@end smalllisp

The control variables described for @code{expect-strings} can also
be used with @code{expect}.
@end defun