   This file documents the MIT Scheme system.

   Copyright (C) 1988-2002 Massachusetts Institute of Technology

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

Condition Handling
==================

   The occurrence of a condition is signalled using `signal-condition'.
`signal-condition' attempts to locate and invoke a "condition handler"
that is prepared to deal with the type of condition that has occurred.
A condition handler is a procedure of one parameter, the condition that
is being signalled.  A procedure is installed as a condition handler by
calling `bind-condition-handler' (to establish a handler that is in
effect only while a particular thunk is executing) or
`bind-default-condition-handler' (to establish a handler that is in
effect permanently).  As implied by the name, handlers created by
`bind-default-condition-handler' are invoked only after all other
applicable handlers have been invoked.

   A HANDLER may process a signal in any way it deems appropriate, but
the common patterns are:

Ignore the condition.
     By returning from the handler in the usual manner.

Handle the condition.
     By doing some processing and then invoking a restart (or, less
     preferably, a continuation) that was established at some point
     prior to the call to `signal-condition'.

Resignal a condition.
     By doing some processing and calling `signal-condition' with either
     the same condition or a newly created one.  In order to support
     this, `signal-condition' runs HANDLER in such a way that a
     subsequent call to `signal-condition' sees only the handlers that
     were established prior to this one.

   As an aid to debugging condition handlers, Scheme maintains a set of
condition types that will cause an interactive breakpoint to occur prior
to normal condition signalling.  That is, `signal-condition' creates a
new REPL prior to its normal operation when its argument is a condition
that is a specialization of any of these types.  The procedure
`break-on-signals' establishes this set of condition types.

 - procedure: ignore-errors thunk
     Executes THUNK with a condition handler that intercepts the
     signalling of any specialization of `condition-type:error'
     (including those produced by calls to `error') and immediately
     terminates the execution of THUNK and returns from the call to
     `ignore-errors' with the signalled condition as its value.  If
     THUNK returns normally, its value is returned from `ignore-errors'.

     Notice that `ignore-errors' does not "turn off signalling" or
     condition handling.  Condition handling takes place in the normal
     manner but conditions specialized from `condition-type:error' are
     trapped rather than propogated as they would be by default.

 - procedure: bind-condition-handler condition-types handler thunk
     Invokes THUNK after adding HANDLER as a condition handler for the
     conditions specified by CONDITION-TYPES.  CONDITION-TYPES must be
     a list of condition types; signalling a condition whose type is a
     specialization of any of these types will cause the HANDLER to be
     invoked.  See `signal-condition' for a description of the
     mechanism used to invoke handlers.

     By special extension, if CONDITION-TYPES is the empty list then
     the HANDLER is called for all conditions.

 - procedure: bind-default-condition-handler condition-types handler
     Installs HANDLER as a (permanent) condition handler for the
     conditions specified by CONDITION-TYPES.  CONDITION-TYPES must be
     a list of condition types; signalling a condition whose type is a
     specialization of any of these types will cause the HANDLER to be
     invoked.  See `signal-condition' for a description of the
     mechanism used to invoke handlers.

     By special extension, if CONDITION-TYPES is the empty list then
     the HANDLER is called for all conditions.

 - procedure: break-on-signals condition-types
     Arranges for `signal-condition' to create an interactive REPL
     before it signals a condition that is a specialization of any of
     the types in the list of CONDITION-TYPES.  This can be extremely
     helpful when trying to debug code that uses custom condition
     handlers.  In order to create a REPL when _any_ condition type is
     signalled it is best to actually put a breakpoint on entry to
     `signal-condition'.

 - procedure: standard-error-handler condition
     Called internally by `error' after it calls `signal-condition'.
     Normally creates creates a new REPL with the prompt `"error>"'
     (but see `standard-error-hook').  In order to simulate the effect
     of calling `error', code may call `signal-condition' directly and
     then call `standard-error-handler' if `signal-condition' returns.

 - variable: standard-error-hook
     This variable controls the behavior of the procedure
     `standard-error-handler', and hence `error'.  It is intended to be
     bound with `fluid-let' and is normally `#f'.  It may be changed to
     a procedure of one argument and will then be invoked (with
     `standard-error-hook' rebound to `#f') by `standard-error-handler'
     just prior to starting the error REPL.  It is passed one argument,
     the condition being signalled.

 - procedure: standard-warning-handler condition
     This is the procedure called internally by `warn' after it calls
     `signal-condition'.  The normal behavior of
     `standard-warning-handler' is to print a message (but see
     `standard-warning-hook').  More precisely, the message is printed
     to the port returned by `notification-output-port'.  The message is
     formed by first printing the string `"Warning: "' to this port, and
     then calling `write-condition-report' on CONDITION and the port.

     In order to simulate the effect of calling `warn', code may call
     `signal-condition' directly and then call
     `standard-warning-handler' if `signal-condition' returns.  (This
     is not sufficient to implement the `muffle-warning' protocol,
     however.  For that purpose an explicit restart must be provided.)

 - variable: standard-warning-hook
     This variable controls the behavior of the procedure
     `standard-warning-handler', and hence `warn'.  It is intended to
     be bound with `fluid-let' and is normally `#f'.  It may be changed
     to a procedure of one argument and will then be invoked (with
     `standard-warning-hook' rebound to `#f') by
     `standard-warning-handler' in lieu of writing the warning message.
     It is passed one argument, the condition being signalled.

Restarts
========

   The Scheme error system provides a mechanism, known as "restarts",
that helps coordinate condition-signalling code with condition-handling
code.  A module of code that detects and signals conditions can provide
procedures (using `with-simple-restart' or `with-restart') to be
invoked by handlers that wish to continue, abort, or restart the
computation.  These procedures, called "restart effectors", are
encapsulated in restart objects.

   When a condition object is created, it contains a set of restart
objects, each of which contains a restart effector.  Condition handlers
can inspect the condition they are handling (using `find-restart' to
find restarts by name, or `condition/restarts' to see the entire set),
and they can invoke the associated effectors (using `invoke-restart' or
`invoke-restart-interactively').  Effectors can take arguments, and
these may be computed directly by the condition-handling code or by
gathering them interactively from the user.

   The names of restarts can be chosen arbitrarily, but the choice of
name is significant.  These names are used to coordinate between the
signalling code (which supplies names for restarts) and the handling
code (which typically chooses a restart effector by the name of its
restart).  Thus, the names specify the "restart protocol" implemented
by the signalling code and invoked by the handling code.  The protocol
indicates the number of arguments required by the effector code as well
as the semantics of the arguments.

   Scheme provides a conventional set of names (hence, protocols) for
common use.  By choosing the names of restarts from this set, signalling
code can indicate that it is able to perform a small set of fairly
common actions (`abort', `continue', `muffle-warning', `retry',
`store-value', `use-value').  In turn, simple condition-handling code
can look for the kind of action it wishes to perform and simply invoke
it by name.  All of Scheme's conventional names are symbols, although
in general restart names are not restricted to any particular data
type.  In addition, the object `#f' is reserved to indicate the "not
for automated use" protocol: these restarts should be activated only
under human control.

   Restarts themselves are first-class objects.  They encapsulate their
name, a procedure (known as the EFFECTOR) to be executed if they are
invoked, and a thunk (known as the REPORTER) that can be invoked to
display a description of the restart (used, for example, by the
interactive debugger).  Invoking a restart is an indication that a
handler has chosen to accept control for a condition; as a consequence,
the EFFECTOR of the restart should not return, since this would
indicate that the handler declined to handle the condition.  Thus, the
EFFECTOR should call a continuation captured before the
condition-signalling process began.  The most common pattern of usage by
signalling code is encapsulated in `with-simple-restart'.

   Within this chapter, a parameter named RESTARTS will accept any of
the following values:

   * A list of restart objects.

   * A condition.  The procedure `condition/restarts' is called on the
     condition, and the resulting list of restarts is used in place of
     the condition.

   * The symbol `bound-restarts'.  The procedure `bound-restarts' is
     called (with no arguments), and the resulting list of restarts is
     used in place of the symbol.

   * If the RESTARTS parameter is optional and is not supplied, it is
     equivalent to having specified the symbol `bound-restarts'.

Establishing Restart Code
-------------------------

 - procedure: with-simple-restart name reporter thunk
     Invokes THUNK in a dynamic environment created by adding a restart
     named NAME to the existing named restarts.  REPORTER may be used
     during the execution of THUNK to produce a description of the
     newly created restart; it must either be a procedure of one
     argument (a port) or a string.  By convention, the description
     generated by REPORTER should be a short complete sentence, with
     first word capitalized and terminated by a period.  The sentence
     should fit on one line with a little room to spare (see the
     examples below); usually this means that the sentence should be 70
     characters or less in length.

     If the restart created by `with-simple-restart' is invoked it
     simply aborts the computation in progress by returning an
     unspecified value from the call to `with-simple-restart'.
     Otherwise `with-simple-restart' returns the value computed by
     THUNK.

     (with-simple-restart 'george "This restart is named george."
       (lambda () 3)) => 3

     (with-simple-restart 'george "This restart is named george."
       (lambda ()
         (invoke-restart (find-restart 'george)))) => `unspecific'

     (with-simple-restart 'george "This restart is named george."
       (lambda () (car 3)))
     ;The object 3, passed as the first argument to car,
     ; is not the correct type.
     ;To continue, call RESTART with an option number:
     ; (RESTART 3) => Specify an argument to use in its place.
     ; (RESTART 2) => This restart is named george.
     ; (RESTART 1) => Return to read-eval-print level 1.

 - procedure: with-restart name reporter effector interactor thunk
     Invokes THUNK in a dynamic environment created by adding a restart
     named NAME to the existing named restarts.  REPORTER may be used
     during the execution of THUNK to produce a description of the
     newly created restart; it must either be a procedure of one
     argument (a port) or a string.  EFFECTOR is a procedure which will
     be called when the restart is invoked by `invoke-restart'.
     INTERACTOR specifies the arguments that are to be passed to
     EFFECTOR when it is invoked interactively; it may be either a
     procedure of no arguments, or `#f'.  If INTERACTOR is `#f', this
     restart is not meant to be invoked interactively.

     The value returned by `with-restart' is the value returned by
     THUNK.  Should the restart be invoked by a condition handler,
     however, the EFFECTOR will not return back to the handler that
     invoked it.  Instead, the EFFECTOR should call a continuation
     created before the condition-signalling process began, and
     `with-restart' will therefore not return in the normal manner.

     (define (by-george! thunk)
       ; This code handles conditions that arise while executing THUNK
       ; by invoking the GEORGE restart, passing 1 and 2 to the restart's
       ; EFFECTOR code.
       (bind-condition-handler '() ; All conditions
        (lambda (condition)
          (invoke-restart (find-restart 'george) 1 2))
        thunk))

     (define (can-george! thunk)
       ; This code provides a way of handling errors: the GEORGE restart.
       ; In order to GEORGE you must supply two values.
       (lambda ()
         (call-with-current-continuation
          (lambda (kappa)
            (with-restart
             'george                         ; Name
             "This restart is named george." ; Reporter
             (lambda (a b)                   ; Effector
               (kappa (list 'george a b)))
             values                          ; Interactor
             thunk)))))                      ; Thunk

     (by-george! (can-george! (lambda () -3))        => -3
     (by-george! (can-george! (lambda () (car 'x)))) => (george 1 2)

Invoking Standard Restart Code
------------------------------

   Scheme supports six standard protocols for restarting from a
condition, each encapsulated using a named restart (for use by
condition-signalling code) and a simple procedure (for use by
condition-handling code).  Unless otherwise specified, if one of these
procedures is unable to find its corresponding restart, it returns
immediately with an unspecified value.

   Each of these procedures accepts an optional argument RESTARTS,
which is described above in Restarts.

 - procedure: abort [restarts]
     Abort the computation, using the restart named `abort'.  The
     corresponding effector takes no arguments and abandons the current
     line of computation.  This is the restart provided by Scheme's
     REPL.

     If there is no restart named `abort', this procedure signals an
     error of type `condition-type:no-such-restart'.

 - procedure: continue [restarts]
     Continue the current computation, using the restart named
     `continue'.  The corresponding effector takes no arguments and
     continues the computation beyond the point at which the condition
     was signalled.

 - procedure: muffle-warning [restarts]
     Continue the current computation, using the restart named
     `muffle-warning'.  The corresponding effector takes no arguments
     and continues the computation beyond the point at which any warning
     message resulting from the condition would be presented to the
     user.  The procedure `warn' establishes a `muffle-warning' restart
     for this purpose.

     If there is no restart named `muffle-warning', this procedure
     signals an error of type `condition-type:no-such-restart'.

 - procedure: retry [restarts]
     Retry the current computation, using the restart named `retry'.
     The corresponding effector takes no arguments and simply retries
     the same computation that triggered the condition.  The condition
     may reoccur, of course, if the root cause has not been eliminated.
     The code that signals a "file does not exist" error can be
     expected to supply a `retry' restart.  The restart would be
     invoked after first creating the missing file, since the
     computation is then likely to succeed if it is simply retried.

 - procedure: store-value new-value [restarts]
     Retry the current computation, using the restart named
     `store-value', after first storing NEW-VALUE.  The corresponding
     effector takes one argument, NEW-VALUE, and stores it away in a
     restart-dependent location, then retries the same computation that
     triggered the condition.  The condition may reoccur, of course, if
     the root cause has not been eliminated.  The code that signals an
     "unassigned variable" error can be expected to supply a
     `store-value' restart; this would store the value in the variable
     and continue the computation.

 - procedure: use-value new-value [restarts]
     Retry the current computation, using the restart named `use-value',
     but substituting NEW-VALUE for a value that previously caused a
     failure.  The corresponding effector takes one argument,
     NEW-VALUE, and retries the same computation that triggered the
     condition with the new value substituted for the failing value.
     The condition may reoccur, of course, if the new value also
     induces the condition.

     The code that signals an "unassigned variable" error can be
     expected to supply a `use-value' restart; this would simply
     continue the computation with NEW-VALUE instead of the value of
     the variable.  Contrast this with the `retry' and `store-value'
     restarts.  If the `retry' restart is used it will fail because the
     variable still has no value.  The `store-value' restart could be
     used, but it would alter the value of the variable, so that future
     references to the variable would not be detected.

Finding and Invoking General Restart Code
-----------------------------------------

   Restarts are a general mechanism for establishing a protocol between
condition-signalling and condition-handling code.  The Scheme error
system provides "packaging" for a number of common protocols.  It also
provides lower-level hooks that are intended for implementing customized
protocols.  The mechanism used by signalling code (`with-restart' and
`with-simple-restart') is used for both purposes.

   Four additional operations are provided for the use of
condition-handling code.  Two operations (`bound-restarts' and
`find-restart') allow condition-handling code to locate active
restarts.  The other two operations (`invoke-restart' and
`invoke-restart-interactively') allow restart effectors to be invoked
once the restart object has been located.

   In addition, there is a data abstraction that provides access to the
information encapsulated in restart objects.

 - procedure: bound-restarts
     Returns a list of all currently active restart objects, most
     recently installed first.  `bound-restarts' should be used with
     caution by condition-handling code, since it reveals all restarts
     that are active at the time it is called, rather than at the time
     the condition was signalled.  It is useful, however, for
     collecting the list of restarts for inclusion in newly generated
     condition objects or for inspecting the current state of the
     system.

 - procedure: find-restart name [restarts]
     Returns the first restart object named NAME in the list of
     RESTARTS (permissible values for RESTARTS are described above in
     Restarts).  When used in a condition handler,
     `find-restart' is usually passed the name of a particular restart
     _and_ the condition object that has been signalled.  In this way
     the handler finds only restarts that were available when the
     condition was created (usually the same as when it was signalled).
     If RESTARTS is omitted, the currently active restarts would be
     used, and these often include restarts added after the condition
     ocurred.

 - procedure: invoke-restart restart argument...
     Calls the restart effector encapsulated in RESTART, passing the
     specified ARGUMENTs to it.  `invoke-restart' is intended for use
     by condition-handling code that understands the protocol
     implemented by RESTART, and can therefore calculate and pass an
     appropriate set of arguments.

     If a condition handler needs to interact with a user to gather the
     arguments for an effector (e.g. if it does not understand the
     protocol implemented by RESTART) `invoke-restart-interactively'
     should be used instead of `invoke-restart'.

 - procedure: invoke-restart-interactively restart
     First calls the interactor encapsulated in RESTART to
     interactively gather the arguments needed for RESTART's effector.
     It then calls the effector, passing these arguments to it.

     `invoke-restart-interactively' is intended for calling interactive
     restarts (those for which `restart/interactor' is not `#f').  For
     convenience, `invoke-restart-interactively' will call the
     restart's effector with no arguments if the restart has no
     interactor; this behavior may change in the future.

The Named Restart Abstraction
-----------------------------

   A restart object is very simple, since it encapsulates only a name,
effector, interactor, and description.

 - procedure: restart? object
     Returns `#f' if and only if OBJECT is not a restart.

 - procedure: restart/name restart
     Returns the name of RESTART.  While the Scheme error system uses
     only symbols and the object `#f' for its predefined names, programs
     may use arbitrary objects (name equivalence is tested using `eq?').

 - procedure: restart/effector restart
     Returns the effector encapsulated in RESTART.  Normally this
     procedure is not used since `invoke-restart' and
     `invoke-restart-interactively' capture the most common invocation
     patterns.

 - procedure: restart/interactor restart
     Returns the interactor encapsulated in RESTART.  This is either a
     procedure of no arguments or the object `#f'.  Normally this
     procedure is not used since `invoke-restart-interactively' captures
     the most common usage.  Thus `restart/interactor' is most useful as
     a predicate to determine if RESTART is intended to be invoked
     interactively.

 - procedure: write-restart-report restart port
     Writes a description of RESTART to PORT.  This works by either
     displaying (if it is a string) or calling (if it is a procedure)
     the REPORTER that was supplied when the restart was created.

Condition Instances
===================

   A "condition", in addition to the information associated with its
type, usually contains other information that is not shared with other
conditions of the same type.  For example, the condition type associated
with "unbound variable" errors does not specify the name of the
variable that was unbound.  The additional information is captured in a
"condition" object, also called a "condition instance".

   In addition to information that is specific to a given type of
condition (such as the variable name for "unbound variable"
conditions), every condition instance also contains a continuation that
encapsulates the state of the computation in which the condition
occurred.  This continuation is used for analyzing the computation to
learn more about the context in which the condition occurred. It is
_not_ intended to provide a mechanism for continuing the computation;
that mechanism is provided by restarts.

Generating Operations on Conditions
-----------------------------------

   Scheme provides four procedures that take a condition type as input
and produce operations on the corresponding condition object.  These are
reminiscent of the operations on record types that produce record
operators (see Records).  Given a condition type it is possible to
generate: a constructor for instances of the type (using
`condition-constructor'); an accessor to extract the contents of a
field in instances of the type (using `condition-accessor'); a
predicate to test for instances of the type (using
`condition-predicate'); and a procedure to create and signal an
instance of the type (using `condition-signaller').

   Notice that the creation of a condition object is distinct from
signalling an occurrence of the condition.  Condition objects are
first-class; they may be created and never signalled, or they may be
signalled more than once.  Further notice that there are no procedures
for modifying conditions; once created, a condition cannot be altered.

 - procedure: condition-constructor condition-type field-names
     Returns a constructor procedure that takes as arguments values for
     the fields specified in FIELD-NAMES and creates a condition of type
     CONDITION-TYPE.  FIELD-NAMES must be a list of symbols that is a
     subset of the FIELD-NAMES in CONDITION-TYPE.  The constructor
     procedure returned by `condition-constructor' has signature

          (lambda (CONTINUATION RESTARTS . FIELD-VALUES) ...)

     where the FIELD-NAMES correspond to the FIELD-VALUES.  The
     constructor argument RESTARTS is described in Restarts.
     Conditions created by the constructor procedure have `#f' for the
     values of all fields other than those specified by FIELD-NAMES.

     For example, the following procedure `make-simple-warning'
     constructs a condition of type `condition-type:simple-warning'
     given a continuation (where the condition occurred), a description
     of the restarts to be made available, a warning message, and a
     list of irritants that caused the warning:

          (define make-simple-warning
            (condition-constructor condition-type:simple-warning
                                   '(message irritants)))

 - procedure: condition-accessor condition-type field-name
     Returns a procedure that takes as input a condition object of type
     CONDITION-TYPE and extracts the contents of the specified
     FIELD-NAME.  `condition-accessor' signals
     `error:bad-range-argument' if the FIELD-NAME isn't one of the
     named fields of CONDITION-TYPE; the returned procedure will signal
     `error:wrong-type-argument' if passed an object other than a
     condition of type CONDITION-TYPE or one of its specializations.

     If it is known in advance that a particular field of a condition
     will be accessed repeatedly it is worth constructing an accessor
     for the field using `condition-accessor' rather than using the
     (possibly more convenient, but slower) `access-condition'
     procedure.

 - procedure: condition-predicate condition-type
     Returns a predicate procedure for testing whether an object is a
     condition of type CONDITION-TYPE or one of its specializations
     (there is no predefined way to test for a condition of a given
     type but _not_ a specialization of that type).

 - procedure: condition-signaller condition-type field-names
          default-handler
     Returns a signalling procedure with parameters FIELD-NAMES.  When
     the signalling procedure is called it creates and signals a
     condition of type CONDITION-TYPE.  If the condition isn't handled
     (i.e. if no handler is invoked that causes an escape from the
     current continuation) the signalling procedure reduces to a call
     to DEFAULT-HANDLER with the condition as its argument.

     There are several standard procedures that are conventionally used
     for DEFAULT-HANDLER.  If CONDITION-TYPE is a specialization of
     `condition-type:error', DEFAULT-HANDLER should be the procedure
     `standard-error-handler'.  If CONDITION-TYPE is a specialization
     of `condition-type:warning', DEFAULT-HANDLER should be the
     procedure `standard-warning-handler'.  If CONDITION-TYPE is a
     specialization of `condition-type:breakpoint', DEFAULT-HANDLER
     should be the procedure `standard-breakpoint-handler'.

Condition Abstraction
---------------------

   The condition data type is abstracted through a predicate
`condition?' and a set of accessor procedures.

 - procedure: condition? object
     Returns `#f' if and only if OBJECT is not a condition.

 - procedure: condition/type condition
     Returns the condition type of which CONDITION is an instance.

 - procedure: condition/error? condition
     Returns `#t' if the CONDITION is an instance of condition type
     `condition-type:error' or a specialization of it, `#f' otherwise.

 - procedure: condition/restarts condition
     Returns the list of restarts specified when CONDITION was created.

 - procedure: condition/continuation condition
     Returns the continuation specified when CONDITION was created.
     This is provided for inspecting the state of the system when the
     condition occurred, _not_ for continuing or restarting the
     computation.

 - procedure: write-condition-report condition port
     Writes a description of CONDITION to PORT, using the reporter
     function from the condition type associated with CONDITION.  See
     also `condition/report-string'.

Simple Operations on Condition Instances
----------------------------------------

   The simple procedures described in this section are built on top of
the more detailed abstraction of condition objects described above.
While these procedures are sometimes easier to use, they are often less
efficient.

 - procedure: make-condition condition-type continuation restarts
          field-plist
     Create a new condition object as an instance of CONDITION-TYPE,
     associated with CONTINUATION.  The CONTINUATION is provided for
     inspection purposes only, _not_ for restarting the computation.
     The RESTARTS argument is described in Restarts.  The
     FIELD-PLIST is an alternating list of field names and values for
     those fields, where the field names are those that would be
     returned by `(condition-type/field-names CONDITION-TYPE)'.  It is
     used to provide values for fields in the condition object; fields
     with no value specified are set to `#f'.  Once a condition object
     has been created there is no way to alter the values of these
     fields.

 - procedure: access-condition condition field-name
     Returns the value stored in the field FIELD-NAME within CONDITION.
     FIELD-NAME must be one of the names returned by
     `(condition-type/field-names (condition/type CONDITION))'.
     `access-condition' looks up the FIELD-NAME at runtime, so it is
     more efficient to use `condition-accessor' to create an access
     function if the same field is to be extracted from several
     instances of the same condition type.

 - procedure: condition/report-string condition
     Returns a string containing a report of the CONDITION.  This is
     generated by calling `write-condition-report' on CONDITION and a
     string output port, and returning the output collected by the port
     as a string.

Condition Types
===============

   Each condition has a "condition type" object associated with it.
These objects are used as a means of focusing on related classes of
conditions, first by concentrating all of the information about a
specific class of condition in a single place, and second by specifying
an inheritance relationship between types.  This inheritance
relationship forms the taxonomic structure of the condition hierarchy
(see Taxonomy).

   The following procedures consititute the abstraction for condition
types.

 - procedure: make-condition-type name generalization field-names
          reporter
     Creates and returns a (new) condition type that is a
     specialization of GENERALIZATION (if it is a condition type) or is
     the root of a new tree of condition types (if GENERALIZATION is
     `#f').  For debugging purposes, the condition type has a NAME, and
     instances of this type contain storage for the fields specified by
     FIELD-NAMES (a list of symbols) in addition to the fields common
     to all conditions (TYPE, CONTINUATION and RESTARTS).

     REPORTER is used to produce a description of a particular
     condition of this type.  It may be a string describing the
     condition, a procedure of arity two (the first argument will be a
     condition of this type and the second a port) that will `write'
     the message to the given port, or `#f' to specify that the
     reporter should be taken from the condition type GENERALIZATION
     (or produce an "undocumented condition of type ..." message if
     GENERALIZATION is `#f').  The conventions used to form
     descriptions are spelled out in Error Messages.

 - procedure: condition-type/error? condition-type
     Returns `#t' if the CONDITION-TYPE is `condition-type:error' or a
     specialization of it, `#f' otherwise.

 - procedure: condition-type/field-names condition-type
     Returns a list of all of the field names for a condition of type
     CONDITION-TYPE.  This is the set union of the fields specified
     when this CONDITION-TYPE was created with the
     `condition-type/field-names' of the generalization of this
     CONDITION-TYPE.

 - procedure: condition-type/generalizations condition-type
     Returns a list of all of the generalizations of CONDITION-TYPE.
     Notice that every condition type is considered a generalization of
     itself.

 - procedure: condition-type? object
     Returns `#f' if and only if OBJECT is not a condition type.