   This file documents the use of MIT Scheme.

   Copyright (C) 1991-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".

Coding style
------------

   Scheme is a rich language, in which there are usually several ways to
say the same thing.  A "coding style" is a set of rules that a
programmer uses for choosing an expressive form to use in a given
situation.  Usually these rules are aesthetic, but sometimes there are
efficiency issues involved; this section describes a few choices that
have non-obvious efficiency consequences.

Better predicates
.................

   Consider the following implementation of `map' as might be found in
any introductory book on Scheme:

     (define (map f lst)
       (if (null? lst)
           '()
           (cons (f (car lst)) (map f (cdr lst)))))

   The problem with this definition is that at the points where `car'
and `cdr' are called we still do not know that LST is a pair.  The
compiler must insert a type check, or if type checks are disabled, the
program might give wrong results.  Since one of the fundamental
properties of `map' is that it transforms lists, we should make the
relationship between the input pairs and the result pairs more apparent
in the code:

     (define (map f lst)
       (cond ((pair? lst)
              (cons (f (car lst)) (map f (cdr lst))))
             ((null? lst)
              '())
             (else
              (error "Not a proper list:"  lst))))

   Note also that the `pair?' case comes first because we expect that
`map' will be called on lists which have, on average, length greater
that one.

Internal procedures
...................

   Calls to internal procedures are faster than calls to global
procedures.  There are two things that make internal procedures faster:
First, the procedure call is compiled to a direct jump to a known
location, which is more efficient that jumping `via' a global binding.
Second, there is a knock-on effect: since the compiler can see the
internal procedure, the compiler can analyze it and possibly produce
better code for other expressions in the body of the loop too:

     (define (map f original-lst)
       (let walk ((lst original-lst))
         (cond ((pair? lst)
                (cons (f (car lst)) (walk (cdr lst))))
               ((null? lst)
                '())
               (else
                (error "Not a proper list:"  original-lst)))))

Internal defines
................

   Internal definitions are a useful tool for structuring larger
procedures.  However, certain internal definitions can thwart compiler
optimizations.  Consider the following two procedures, where
`compute-100' is some unknown procedure that we just know returns `100'.

     (define (f1)
       (define v 100)
       (lambda () v))

     (define (f2)
       (define v (compute-100))
       (lambda () v))

   The procedure returned by `f1' will always give the same result and
the compiler can prove this.  The procedure returned by `f2' may return
different results, even if `f2' is only called once.  Because of this,
the compiler has to allocate a memory cell to `v'.  How can the
procedure return different results?

   The fundamental reason is that the continuation may escape during the
evaluation of `(compute-100)', allowing the rest of the body of `f2' to
be executed _again_:

     (define keep)

     (define (compute-100)
       (call-with-current-continuation
        (lambda (k)
          (set! keep k)
          100)))

     (define p (f2))

     (p)                => 100
     (keep -999)        => p     _re-define v and p_
     (p)                => -999

   To avoid the inefficiency introduced to handle the general case, the
compiler must prove that the continuation cannot possibly escape.  The
compiler knows that lambda expressions and constants do not let their
continuations escape, so order the internal definitions so that
definitions of the following forms come first:

     (define x '_something_)
     (define x (lambda (...) ...))
     (define (f u v) ...)

   Note: The IEEE Scheme standard permits _only_ lambda expressions and
constants as the value of internal defines.  Furthermore, all internal
definitions must appear before any other expressions in the body.
Following the standard simultaneously assures portability and avoids
the implementation inefficiencies described in this section.

Global variables
----------------

   Compiled code usually accesses variables in top-level first-class
environments via _variable caches_.  Each compiled procedure has a set
of variable caches for the global variables that it uses.  There are
three kinds of variable cache - read caches for getting the value of a
variable (referencing the variable), write caches for changing the
value, and execute caches for calling the procedure assigned to that
variable.

   Sometimes the variable caches contain special objects, called
reference traps, that indicate that the operation cannot proceed
normally and must either be completed by the system (in order to keep
the caches coherent) or must signal an error.  For example, the
assignment

     (set! newline my-better-newline)

   will cause the system to go to each compiled procedure that calls
`newline' and update its execute cache to call the new procedure.
Obviously you want to avoid updating hundreds of execute caches in a
critical loop.  Using `fluid-let' to temporarily redefine a procedure
has the same inefficiency (but twice!).

   To behave correctly in all situations, each variable reference or
assignment must check for the reference traps.

   Sometimes you can prove that the variable (a) will always be bound,
(b) will never be unassigned, and (c) there will never be any compiled
calls to that variable.  The compiler can't prove this because it
assumes that other independently compiled files might be loaded that
invalidate these assumptions.  If you know that these conditions hold,
the following declarations can speed up and reduce the size of a
program that uses global variables.

 - declaration+: ignore-reference-traps variables
     This declaration tells the compiler that it need not check for
     reference-trap objects when referring to the given VARIABLES.  If
     any of the VARIABLES is unbound or unassigned then a variable
     reference will yield a reference-trap object rather than signaling
     an error.  This declaration is relatively safe: the worst that can
     happen is that a reference-trap object finds its way into a data
     structure (e.g. a list) or into interpreted code, in which case it
     will probably cause some `unrelated' variable to mysteriously
     become unbound or unassigned.

 - declaration+: ignore-assignment-traps variables
     This declaration tells the compiler that it need not check for
     reference-trap objects when assigning to the given VARIABLES.  An
     assignment to a variable that ignores assignment traps can cause a
     great deal of trouble.  If there is a compiled procedure call
     anywhere in the system to this variable, the execute caches will
     not be updated, causing an inconsistency between the value used
     for the procedure call and the value seen by reading the variable.
     This mischief is compounded by the fact that the assignment can
     cause other assignments that were compiled with checks to behave
     this way too.

   The VARIABLES are specified with expressions from the following set
language:

 - variable-specification: set name ...
     All of the explicitly listed names.

 - variable-specification: all
 - variable-specification: none
 - variable-specification: free
 - variable-specification: bound
 - variable-specification: assigned
     These expressions name sets of variables. `all' is the set of all
     variables, `none' is the empty set, `free' is all of the variables
     bound outside the current block, `bound' is all of the variables
     bound in the current block and `assigned' is all of the variables
     for which there exists an assignment (i.e. `set!').

 - variable-specification: union set1 set2
 - variable-specification: intersection set1 set2
 - variable-specification: difference set1 set2
     For example, to ignore reference traps on all the variables except
     X, Y and any variable that is assigned to

          (declare (ignore-reference-traps
                    (difference all (union assigned (set x y)))))

Fixnum arithmetic
-----------------

   The usual arithmetic operations like `+' and `<' are called generic
arithmetic operations because they work for all (appropriate) kinds of
number.

   A "fixnum" is an exact integer that is small enough to fit in a
machine word.  In MIT Scheme, fixnums are 26 bits on 32-bit machines,
and 56 bits on 64-bit machines; it is reasonable to assume that fixnums
are at least 24 bits.  Fixnums are signed; they are encoded using 2's
complement.

   All exact integers that are small enough to be encoded as fixnums are
always encoded as fixnums -- in other words, any exact integer that is
not a fixnum is too big to be encoded as such.  For this reason, small
constants such as `0' or `1' are guaranteed to be fixnums.  In
addition, the lengths of and valid indexes into strings and vectors are
also always fixnums.

   If you know that a value is always a small fixnum, you can substitute
the equivalent fixnum operation for the generic operation.  However,
care should be exercised: if used improperly, these operations can
return incorrect answers, or even malformed objects that confuse the
garbage collector.  For a listing of all fixnum operations, see
Fixnum Operations (scheme).

   A fruitful area for inserting fixnum operations is in the index
operations in tight loops.

Flonum arithmetic
-----------------

   Getting efficient flonum arithmetic is much more complicated and
harder than getting efficient fixnum arithmetic.

Flonum consing
..............

   One of the main disadvantages of generic arithmetic is that not all
kinds of number fit in a machine register.  Flonums have to be "boxed"
because a 64-bit IEEE floating-point number (the representation that
MIT Scheme uses) does not fit in a regular machine word.  This is true
even on 64-bit architectures because some extra bits are needed to
distinguish floating-point numbers from other objects like pairs and
strings.  Values are boxed by storing them in a small record in the
heap.  Every floating-point value that you see at the REPL is boxed.
Floating-point values are unboxed only for short periods of time when
they are in the machine's floating-point unit and actual floating-point
operations are being performed.

   Numerical calculations that happen to be using floating-point numbers
cause many temporary floating-point numbers to be allocated.  It is not
uncommon for numerical programs to spend over half of their time
creating and garbage collecting the boxed flonums.

   Consider the following procedure for computing the distance of a
point (X,Y) from the origin.

     (define (distance x y)
       (sqrt (+ (* x x) (* y y))))

   The call `(distance 0.3 0.4)' returns a new, boxed flonum, 0.5.  The
calculation also generates three intermediate boxed flonums.  This next
version works only for flonum inputs, generates only one boxed flonum
(the result) and runs eight times faster:

     (define (flo:distance x y)
       (flo:sqrt (flo:+ (flo:* x x) (flo:* y y))))

   Note that `flo:' operations are usually effective only within a
single arithmetic expression.  If the expression contains conditionals
or calls to procedures then the values tend to get boxed anyway.

Flonum vectors
..............

   Flonum vectors are vectors that contain only floating-point values,
in much the same way as a string is a `vector' containing only character
values.

   Flonum vectors have the advantages of compact storage (about half
that of a conventional vector of flonums) and judicious use of flonum
vectors can decrease flonum consing.

   The disadvantages are that flonum vectors are incompatible with
ordinary vectors, and if not used carefully, can increase flonum
consing.  Flonum vectors are a pain to use because they require you to
make a decision about the representation and stick with it, and it
might not be easy to ascertain whether the advantages in one part of
the program outweigh the disadvantages in another.

   The flonum vector operations are:

 - procedure+: flo:vector-cons n
     Create a flonum vector of length N.  The contents of the vector
     are arbitrary and might not be valid floating-point numbers.  The
     contents should not be used until initialized.

 - procedure+: flo:vector-ref flonum-vector index
 - procedure+: flo:vector-set! flonum-vector index value
 - procedure+: flo:vector-length flonum-vector
     These operations are analogous to the ordinary vector operations.

Examples
........

   The following operation causes no flonum consing because the flonum
is loaded directly from the flonum vector into a floating-point machine
register, added, and stored again.  There is no need for a temporary
boxed flonum.

     (flo:vector-set! v 0 (flo:+ (flo:vector-ref v 0) 1.2))

   In this next example, every time `g' is called, a new boxed flonum
has to be created so that a valid Scheme object can be returned.  If
`g' is called more often than the elements of V are changed then an
ordinary vector might be more efficient.

     (define (g i)
       (flo:vector-ref v i))

Common pitfalls
...............

   Pitfall 1: Make sure that your literals are floating-point constants:

     (define (f1 a) (flo:+ a 1))
     (define (f2 a) (flo:+ a 1.))

   `f1' will most likely cause a hardware error, and certainly give the
wrong answer.  `f2' is correct.

   Pitfall 2: It is tempting to insert calls to `exact->inexact' to
coerce values into flonums.  This does not always work because complex
numbers may be exact or inexact too.  Also, the current implementation
of `exact->inexact' is slow.

   Pitfall 3: A great deal of care has to be taken with the standard
math procedures.  For example, when called with a flonum, both `sqrt'
and `asin' can return a complex number (e.g with argument `-1.5').

Debugging
*********

   Parts of this chapter are adapted from `Don't Panic: A 6.001 User's
Guide to the Chipmunk System', by Arthur A. Gleckler.

   Even computer software that has been carefully planned and well
written may not always work correctly.  Mysterious creatures called
"bugs" may creep in and wreak havoc, leaving the programmer to clean up
the mess.  Some have theorized that a program fails only because its
author made a mistake, but experienced computer programmers know that
bugs are always to blame.  This is why the task of fixing broken
computer software is called "debugging".

   It is impossible to prove the correctness of any non-trivial program;
hence the Cynic's First Law of Debugging:

     Programs don't become more reliable as they are debugged; the bugs
     just get harder to find.

   Scheme is equipped with a variety of special software for finding and
removing bugs.  The debugging tools include facilities for tracing a
program's use of specified procedures, for examining Scheme
environments, and for setting "breakpoints", places where the program
will pause for inspection.

   Many bugs are detected when programs try to do something that is
impossible, like adding a number to a symbol, or using a variable that
does not exist; this type of mistake is called an "error".  Whenever an
error occurs, Scheme prints an error message and starts a new REPL.
For example, using a nonexistent variable `foo' will cause Scheme to
respond

     1 ]=> foo

     ;Unbound variable: foo
     ;To continue, call RESTART with an option number:
     ; (RESTART 3) => Specify a value to use instead of foo.
     ; (RESTART 2) => Define foo to a given value.
     ; (RESTART 1) => Return to read-eval-print level 1.

     2 error>

   Sometimes, a bug will never cause an error, but will still cause the
program to operate incorrectly.  For instance,

     (prime? 7)   =>   #f

   In this situation, Scheme does not know that the program is
misbehaving.  The programmer must notice the problem and, if necessary,
start the debugging tools manually.

   There are several approaches to finding bugs in a Scheme program:

   * Inspect the original Scheme program.

   * Use the debugging tools to follow your program's progress.

   * Edit the program to insert checks and breakpoints.

Only experience can teach how to debug programs, so be sure to
experiment with all these approaches while doing your own debugging.
Planning ahead is the best way to ward off bugs, but when bugs do
appear, be prepared to attack them with all the tools available.

Subproblems and Reductions
==========================

   Understanding the concepts of "reduction" and "subproblem" is
essential to good use of the debugging tools.  The Scheme interpreter
evaluates an expression by "reducing" it to a simpler expression.  In
general, Scheme's evaluation rules designate that evaluation proceeds
from one expression to the next by either starting to work on a
"subexpression" of the given expression, or by reducing the entire
expression to a new (simpler, or reduced) form.  Thus, a history of the
successive forms processed during the evaluation of an expression will
show a sequence of subproblems, where each subproblem may consist of a
sequence of reductions.

   For example, both `(+ 5 6)' and `(+ 7 9)' are subproblems of the
following combination:

     (* (+ 5 6) (+ 7 9))

If `(prime? n)' is true, then `(cons 'prime n)' is a reduction for the
following expression:

     (if (prime? n)
         (cons 'prime n)
         (cons 'not-prime n))

   This is because the entire subproblem of the `if' expression can be
reduced to the problem `(cons 'prime n)', once we know that `(prime?
n)' is true; the `(cons 'not-prime n)' can be ignored, because it will
never be needed.  On the other hand, if `(prime? n)' were false, then
`(cons 'not-prime n)' would be the reduction for the `if' expression.

   The _subproblem level_ is a number representing how far back in the
history of the current computation a particular evaluation is.  Consider
`factorial':

     (define (factorial n)
       (if (< n 2)
           1
           (* n (factorial (- n 1)))))

If we stop `factorial' in the middle of evaluating `(- n 1)', the `(- n
1)' is at subproblem level 0.  Following the history of the computation
"upwards," `(factorial (- n 1))' is at subproblem level 1, and `(* n
(factorial (- n 1)))' is at subproblem level 2.  These expressions all
have _reduction number_ 0.  Continuing upwards, the `if' expression has
reduction number 1.

   Moving backwards in the history of a computation, subproblem levels
and reduction numbers increase, starting from zero at the expression
currently being evaluated.  Reduction numbers increase until the next
subproblem, where they start over at zero.  The best way to get a feel
for subproblem levels and reduction numbers is to experiment with the
debugging tools, especially `debug'.

The Command-Line Debugger
=========================

   There are two debuggers available with MIT Scheme.  One of them runs
under Edwin, and is described in that section of this document (see
Edwin Debugger).  The other is command-line oriented, does not
require Edwin, and is described here.

   The "command-line debugger", called `debug', is the tool you should
use when Scheme signals an error and you want to find out what caused
the error.  When Scheme signals an error, it records all the
information necessary to continue running the Scheme program that caused
the error; the debugger provides you with the means to inspect this
information.  For this reason, the debugger is sometimes called a
"continuation browser".

   Here is the transcript of a typical Scheme session, showing a user
evaluating the expression `(fib 10)', Scheme responding with an unbound
variable error for the variable `fob', and the user starting the
debugger:

     1 ]=> (fib 10)

     ;Unbound variable: fob
     ;To continue, call RESTART with an option number:
     ; (RESTART 3) => Specify a value to use instead of fob.
     ; (RESTART 2) => Define fob to a given value.
     ; (RESTART 1) => Return to read-eval-print level 1.

     2 error> (debug)

     There are 6 subproblems on the stack.

     Subproblem level: 0 (this is the lowest subproblem level)
     Expression (from stack):
         fob
     Environment created by the procedure: FIB
      applied to: (10)
     The execution history for this subproblem contains 1 reduction.
     You are now in the debugger.  Type q to quit, ? for commands.

     3 debug>

This tells us that the error occurred while trying to evaluate the
expression `fob' while running `(fib 10)'.  It also tells us this is
subproblem level 0, the first of 6 subproblems that are available for
us to examine.  The expression shown is marked `(from stack)', which
tells us that this expression was reconstructed from the interpreter's
internal data structures.  Another source of information is the
"execution history", which keeps a record of expressions evaluated by
the interpreter.  The debugger informs us that the execution history
has recorded some information for this subproblem, specifically a
description of one reduction.

   What follows is a description of the commands available in the
debugger.  To understand how the debugger works, you need to understand
that the debugger has an implicit state that is examined and modified by
commands.  The state consists of three pieces of information: a
"subproblem", a "reduction", and an "environment frame".  Each of these
parts of the implicit state is said to be "selected"; thus one refers
to the "selected subproblem", and so forth.  The debugger provides
commands that examine the selected state, and allow you to select
different states.

   Here are the debugger commands.  Each of these commands consists of a
single letter, which is to be typed by itself at the debugger prompt.
It is not necessary to type <RET> after these commands.

Traversing subproblems
     The debugger has several commands for traversing the structure of
     the continuation.  It is useful to think of the continuation as a
     two-dimensional structure: a backbone consisting of subproblems,
     and associated ribs consisting of reductions.  The bottom of the
     backbone is the most recent point in time; that is where the
     debugger is positioned when it starts.  Each subproblem is
     numbered, with `0' representing the most recent time point, and
     ascending integers numbering older time points.  The `u' command
     moves up to older points in time, and the `d' command moves down
     to newer points in time.  The `g' command allows you to select a
     subproblem by number, and the `h' command will show you a brief
     summary of all of the subproblems.

Traversing reductions
     If the subproblem description says that `The execution history for
     this subproblem contains N reductions', then there is a "rib" of
     reductions for this subproblem.  You can see a summary of the
     reductions for this subproblem using the `r' command.  You can
     move to the next reduction using the `b' command; this moves you
     to the next older reduction.  The `f' command moves in the
     opposite direction, to newer reductions.  If you are at the oldest
     reduction for a given subproblem and use the `b' command, you will
     move to the next older subproblem.  Likewise, if you are at the
     newest reduction and use `f', you'll move to the next newer
     subproblem.

Examining subproblems and reductions
     The following commands will show you additional information about
     the currently selected subproblem or reduction.  The `t' command
     will reprint the standard description (in case it has scrolled off
     the screen).  The `l' command will pretty-print (using `pp') the
     subproblem's expression.

Traversing environments
     Nearly all subproblems and all reductions have associated
     environments.  Selecting a subproblem or reduction also selects
     the associated environment.  However, environments are structured
     as a sequence of frames, where each frame corresponds to a block
     of environment variables, as bound by `lambda' or `let'.  These
     frames collectively represent the block structure of a given
     environment.

     Once an environment frame is selected by the debugger, it is
     possible to select the parent frame of that frame (in other words,
     the enclosing block) using the `p' command.  You can subsequently
     return to the original child frame using the `s' command.  The `s'
     command works because the `p' command keeps track of the frames
     that you step through as you move up the environment hierarchy;
     the `s' command just retraces the path of saved frames.  Note that
     selecting a frame using `p' or `s' will print the bindings of the
     newly selected frame.

Examining environments
     The following commands allow you to examine the contents of the
     selected frame.  The `c' command prints the bindings of the
     current frame.  The `a' command prints the bindings of the current
     frame and each of its ancestor frames.  The `e' command enters a
     read-eval-print loop in the selected environment frame;
     expressions typed at that REPL will be evaluated in the selected
     environment.  To exit the REPL and return to the debugger,
     evaluate `(abort->previous)' or use `restart'.  The `v' command
     prompts for a single expression and evaluates it in the selected
     environment.  The `w' command invokes the environment inspector
     (`where'); quitting the environment inspector returns to the
     debugger.  Finally, the `o' command pretty-prints the procedure
     that was called to create the selected environment frame.

Continuing the computation
     There are three commands that can be used to restart the
     computation that you are examining.  The first is the `k' command,
     which shows the currently active restarts, prompts you to select
     one, and passes control to the it.  It is very similar to
     evaluating `(restart)'.

     The other two commands allow you to invoke internal continuations.
     This should not be done lightly; invoking an internal
     continuation can violate assumptions that the programmer made and
     cause unexpected results.  Each of these commands works in the
     same way: it prompts you for an expression, which is evaluated in
     the selected environment to produce a value.  The appropriate
     internal continuation is then invoked with that value as its sole
     argument.  The two commands differ only in which internal
     continuation is to be invoked.

     The `j' command invokes the continuation associated with the
     selected subproblem.  What this means is as follows: when the
     description of a subproblem is printed, it consists of two parts,
     and "expression" and a "subproblem being executed".  The latter is
     usually marked in the former by the specific character sequence
     `###'.  The internal continuation of the subproblem is the code
     that is waiting for the "subproblem being executed" to return a
     value.  So, in effect, you are telling the program what the
     "subproblem being executed" will evaluate to, and bypassing
     further execution of that code.

     The `z' command is slightly different.  It instead invokes the
     continuation that is waiting for the outer "expression" to finish.
     In other words, it is the same as invoking the `j' command in the
     next frame up.  So you can think of this as an abbreviation for
     the `u' command followed by the `j' command.

Wizard commands
     The `m', `x', and `y' commands are for Scheme wizards.  They are
     used to debug the MIT Scheme implementation.  If you want to find
     out what they do, read the source code.

Miscellaneous commands
     The `i' command will reprint the error message for the error that
     was in effect immediately before the debugger started.  The `q'
     command quits the debugger, returning to the caller.  And the `?'
     command prints a brief summary of the debugger's commands.

Debugging Aids
==============

   This section describes additional commands that are useful for
debugging.

 - procedure+: bkpt datum argument ...
     Sets a breakpoint.  When the breakpoint is encountered, DATUM and
     the ARGUMENTs are typed (just as for `error') and a
     read-eval-print loop is entered.  The environment of the
     read-eval-print loop is derived by examining the continuation of
     the call to `bkpt'; if the call appears in a non-tail-recursive
     position, the environment will be that of the call site.  To exit
     from the breakpoint and proceed with the interrupted process, call
     the procedure `continue'.  Sample usage:

          1 ]=> (begin (write-line 'foo)
                       (bkpt 'test-2 'test-3)
                       (write-line 'bar)
                       'done)

          foo
           test-2 test-3
          ;To continue, call RESTART with an option number:
          ; (RESTART 2) => Return from BKPT.
          ; (RESTART 1) => Return to read-eval-print level 1.

          2 bkpt> (+ 3 3)

          ;Value: 6

          2 bkpt> (continue)

          bar
          ;Value: done

 - procedure+: pp object [output-port [as-code?]]
     The `pp' procedure is described in Output Procedures (scheme).
     However, since this is a very useful
     debugging tool, we also mention it here.  `pp' provides two very
     useful functions:

       1. `pp' will print the source code of a given procedure.  Often,
          when debugging, you will have a procedure object but will not
          know exactly what procedure it is.  Printing the procedure
          using `pp' will show you the source code, which greatly aids
          identification.

       2. `pp' will print the fields of a record structure.  If you
          have a compound object pointer, print it using `pp' to see
          the component fields, like this:

               (pp (->pathname "~"))
               -| #[pathname 14 "/usr/home/cph"]
               -| (host #[host 15])
               -| (device unspecific)
               -| (directory (absolute "usr" "home"))
               -| (name "cph")
               -| (type ())
               -| (version unspecific)

          When combined with use of the `#@' syntax, `pp' provides the
          functionality of a simple object inspector.  For example,
          let's look at the fields of the host object from the above
          example:

               (pp #@15)
               -| #[host 15]
               -| (type-index 0)
               -| (name ())

 - procedure+: pa procedure
     `pa' prints the arguments of PROCEDURE.  This can be used to
     remind yourself, for example, of the correct order of the
     arguments to a procedure.

          for-all?
           => #[compiled-procedure 40 ("boole" #x6) #xC #x20ECB0]

          (pa for-all?)
          -| (items predicate)

          (pp for-all?)
          -|(named-lambda (for-all? items predicate)
          -|  (let loop ((items items))
          -|    (or (null? items)
          -|        (and (predicate (car items))
          -|             (loop (cdr items))))))

 - procedure+: where [obj]
     The procedure `where' enters the environment examination system.
     This allows environments and variable bindings to be examined and
     modified.  `where' accepts one-letter commands.  The commands can
     be found by typing `?' to the `where>' prompt.  The optional
     argument, OBJ, is an object with an associated environment: an
     environment, a procedure, or a promise.  If OBJ is omitted, the
     environment examined is the read-eval-print environment from which
     `where' was called (or an error or breakpoint environment if called
     from the debugger).  If a procedure is supplied, `where' lets the
     user examine the closing environment of the procedure.  This is
     useful for debugging procedure arguments and values.

 - procedure+: apropos string [environment [search-parents?]]
     Search an environment for bound names containing STRING and print
     out the matching bound names.  If ENVIRONMENT is specified, it
     must be an environment or package name, and it defaults to the
     current REPL environment.  The flag SEARCH-PARENTS? specifies
     whether the environment's parents should be included in the
     search.  The default is `#f' if ENVIRONMENT is specified, and `#t'
     if ENVIRONMENT is not specified.

          (apropos "search")
          -| #[package 47 (user)]
          -| #[package 48 ()]
          -| list-search-negative
          -| list-search-positive
          -| nt-fs-flag/case-sensitive-search
          -| re-string-search-backward
          -| re-string-search-forward
          -| re-substring-search-backward
          -| re-substring-search-forward
          -| search-ordered-subvector
          -| search-ordered-vector
          -| search-protection-list
          -| string-search-all
          -| string-search-backward
          -| string-search-forward
          -| substring-search-all
          -| substring-search-backward
          -| substring-search-forward
          -| vector-binary-search

Advising Procedures
===================

   Giving advice to procedures is a powerful debugging technique.
`trace' and `break' are useful examples of advice-giving procedures.
Note that the advice system only works for interpreted procedures.

 - procedure+: trace-entry procedure
     Causes an informative message to be printed whenever PROCEDURE is
     entered.  The message is of the form

          [Entering #[compound-procedure 1 foo]
              Args: VAL1
                    VAL2
                    ...]

     where VAL1, VAL2 etc. are the evaluated arguments supplied to the
     procedure.

          (trace-entry fib)
          (fib 3)
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 3]
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 1]
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 2]
          => 3

 - procedure+: trace-exit procedure
     Causes an informative message to be printed when PROCEDURE
     terminates.  The message contains the procedure, its argument
     values, and the value returned by the procedure.

          (trace-exit fib)
          (fib 3)
          -| [1
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 1]
          -| [2
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 2]
          -| [3
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 3]
          => 3

 - procedure+: trace-both procedure
 - procedure+: trace procedure
     Equivalent to calling both `trace-entry' and `trace-exit' on
     PROCEDURE.  `trace' is the same as `trace-both'.

          (trace-both fib)
          (fib 3)
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 3]
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 1]
          -| [1
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 1]
          -| [Entering #[compound-procedure 19 fib]
          -|     Args: 2]
          -| [2
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 2]
          -| [3
          -|       <== #[compound-procedure 19 fib]
          -|     Args: 3]
          => 3

 - procedure+: untrace-entry [procedure]
     Stops tracing the entry of PROCEDURE.  If PROCEDURE is not given,
     the default is to stop tracing the entry of all entry-traced
     procedures.

 - procedure+: untrace-exit [procedure]
     Stops tracing the exit of PROCEDURE.  If PROCEDURE is not given,
     the default is all exit-traced procedures.

 - procedure+: untrace [procedure]
     Stops tracing both the entry to and the exit from PROCEDURE.  If
     PROCEDURE is not given, the default is all traced procedures.

 - procedure+: break-entry procedure
     Like `trace-entry' with the additional effect that a breakpoint is
     entered when PROCEDURE is invoked.  Both PROCEDURE and its
     arguments can be accessed by calling the procedures `*proc*' and
     `*args*', respectively.  Use `restart' or `continue' to continue
     from a breakpoint.

 - procedure+: break-exit procedure
     Like `trace-exit', except that a breakpoint is entered just prior
     to leaving PROCEDURE.  PROCEDURE, its arguments, and the result
     can be accessed by calling the procedures `*proc*', `*args*', and
     `*result*', respectively.  Use `restart' or `continue' to continue
     from a breakpoint.

 - procedure+: break-both procedure
 - procedure+: break procedure
     Sets a breakpoint at the beginning and end of PROCEDURE.  This is
     `break-entry' and `break-exit' combined.

 - procedure+: unbreak [procedure]
     Discontinues the entering of a breakpoint on the entry to and exit
     from PROCEDURE.  If PROCEDURE is not given, the default is all
     breakpointed procedures.

 - procedure+: unbreak-entry [procedure]
     Discontinues the entering of a breakpoint on the entry to
     PROCEDURE.  If PROCEDURE is not given, the default is all
     entry-breakpointed procedures.

 - procedure+: unbreak-exit [procedure]
     Discontinues the entering of a breakpoint on the exit from
     PROCEDURE.  If PROCEDURE is not given, the default is all
     exit-breakpointed procedures.

   The following three procedures are valid only within the dynamic
extent of a breakpoint.  In other words, don't call them unless you are
stopped inside a breakpoint.

 - procedure+: *proc*
     Returns the procedure in which the breakpoint has stopped.

 - procedure+: *args*
     Returns the arguments to the procedure in which the breakpoint has
     stopped.  The arguments are returned as a newly allocated list.

 - procedure+: *result*
     Returns the result yielded by the procedure in which the
     breakpoint has stopped.  This is valid only when in an exit
     breakpoint.

   The following procedures install "advice" procedures that are called
when the advised procedure is entered or exited.  An entry-advice
procedure must accept three arguments: the advised procedure, a list of
the advised procedure's arguments, and the advised procedure's
application environment (that is, the environment in which the
procedure's formal parameters are bound).  An exit-advice procedure must
accept four arguments: the advised procedure, a list of the advised
procedure's arguments, the result yielded by the advised procedure, and
the advised procedure's application environment.

   Note that the trace and breakpoint procedures described above are all
implemented by means of the more general advice procedures, so removing
advice from an advised procedure will also remove traces and
breakpoints.

 - procedure+: advise-entry procedure advice
     ADVICE must be an entry-advice procedure.  ADVICE is attached to
     PROCEDURE, so that whenever PROCEDURE is entered, ADVICE is called.

 - procedure+: advise-exit procedure advice
     ADVICE must be an exit-advice procedure.  ADVICE is attached to
     PROCEDURE, so that whenever PROCEDURE returns, ADVICE is called.

 - procedure+: advice procedure
     Returns the advice procedures, if any, that are attached to
     PROCEDURE.  This is returned as a list of two lists: the first
     list is all of the entry-advice procedures attached to PROCEDURE,
     and the second is all of the exit-advice procedures.

 - procedure+: unadvise-entry [procedure]
     Removes all entry-advice procedures from PROCEDURE.  If PROCEDURE
     is not given, the default is all entry-advised procedures.

 - procedure+: unadvise-exit [procedure]
     Removes exit-advice procedures from PROCEDURE.  If PROCEDURE is
     not given, the default is all exit-advised procedures.

 - procedure+: unadvise [procedure]
     Removes all advice procedures from PROCEDURE. This is a
     combination of `unadvise-entry' and `unadvise-exit'.  If PROCEDURE
     is not given, the default is all advised procedures.

GNU Emacs Interface
*******************

   There is an interface library, called `xscheme', distributed with
MIT Scheme and GNU Emacs, which facilitates running Scheme as a
subprocess of Emacs.  If you wish to use this interface, please install
the version of `xscheme.el' that comes with MIT Scheme, as it is
guaranteed to be correct for your version of Scheme.

   This interface works under unix only, because it requires unix
signals for its operation.  Porting it to either OS/2 or Windows would
require reimplementing the interface to eliminate the use of signals.
We have no plans to do this.

   To invoke Scheme from Emacs, load the `xscheme' library, then use
`M-x run-scheme'.  You may give `run-scheme' a prefix argument, in
which case it will allow you to edit the command line that is used to
invoke Scheme.  _Do not_ remove the `-emacs' option!

   _Note carefully:_ In Emacs 19 and later, the `run-scheme' command
exists, but is different from the one described here!  In order to get
this interface, you must load the `xscheme' library before executing
`run-scheme'.

   Scheme will be started up as a subprocess in a buffer called
`*scheme*'.  This buffer will be in `scheme-interaction-mode' and all
output from the Scheme process will go there.  The mode line for the
`*scheme*' buffer will have this form:

     --**-*scheme*: 1 [Evaluator]           (Scheme Interaction: input)------

The first field, showing `1' in this example, is the level number.

The second field, showing `[Evaluator]' in this example, describes the
type of REPL that is running.  Other values include:

     [Debugger]
     [Where]

The "mode" after `Scheme Interaction' is one of:

`input'
     Scheme is waiting for input.

`run'
     Scheme is running an evaluation.

`gc'
     Scheme is garbage collecting.

   When `xscheme' is loaded, `scheme-mode' is extended to include
commands for evaluating expressions (do `C-h m' in any `scheme-mode'
buffer for the most up-to-date information):

`M-o'
     Evaluates the current buffer (`xscheme-send-buffer').

`M-z'
     Evaluates the current definition (`xscheme-send-definition').  This
     is also bound to `C-M-x'.

`C-M-z'
     Evaluates the current region (`xscheme-send-region').

`C-x C-e'
     Evaluates the expression to the left of point
     (`xscheme-send-previous-expression').  This is also bound to
     `M-<RET>'.

`C-c C-s'
     Selects the `*scheme*' buffer and places you at its end
     (`xscheme-select-process-buffer').

`C-c C-y'
     Yanks the most recently evaluated expression, placing it at point
     (`xscheme-yank-previous-send').  This works only in the `*scheme*'
     buffer.

   The following commands provide interrupt capability:

`C-c C-c'
     Like typing `C-g' when running Scheme without Emacs.
     (`xscheme-send-control-g-interrupt')

`C-c C-x'
     Like typing `C-c C-x' when running Scheme without Emacs.
     (`xscheme-send-control-x-interrupt')

`C-c C-u'
     Like typing `C-c C-u' when running Scheme without Emacs.
     (`xscheme-send-control-u-interrupt')

`C-c C-b'
     Like typing `C-c C-b' when running Scheme without Emacs.
     (`xscheme-send-breakpoint-interrupt')

`C-c C-p'
     Like evaluating `(continue)'.  (`xscheme-send-proceed')

Edwin
*****

   This chapter describes how to start Edwin, the MIT Scheme text
editor.  Edwin is very similar to GNU Emacs -- you should refer to the
GNU Emacs manual for information about Edwin's commands and key
bindings -- except that Edwin's extension language is MIT Scheme, while
GNU Emacs extensions are written in Emacs Lisp.  This manual does not
discuss customization of Edwin.

Starting Edwin
==============

   To use Edwin, start Scheme with the following command-line options:

     scheme -edwin -edit

Alternatively, you can load Edwin by giving the `-edwin' command-line
option and then calling the procedure `edit':

 - procedure+: edit
 - procedure+: edwin
     Enter the Edwin text editor.  If entering for the first time, the
     editor is initialized (by calling `create-editor' with no
     arguments).  Otherwise, the previously-initialized editor is
     reentered.

     The procedure `edwin' is an alias for `edit'.

 - variable+: inhibit-editor-init-file?
     When Edwin is first initialized, it loads your init file (called
     `~/.edwin' under unix, `edwin.ini' on PCs) if you have one.  If
     the Scheme variable `inhibit-editor-init-file?' is true, however,
     your init file will not be loaded even if it exists.  By default,
     this variable is false.

     Note that you can set this variable in your Scheme init file
     (see Customizing Scheme).

 - procedure+: create-editor arg ...
     Initializes Edwin, or reinitializes it if already initialized.
     `create-editor' is normally invoked automatically by `edit'.

     If no ARGs are given, the value of `create-editor-args' is used
     instead.  In other words, the following are equivalent:

          (create-editor)
          (apply create-editor create-editor-args)

     On the other hand, if ARGs are given, they are used to update
     `create-editor-args', making the following equivalent:

          (apply create-editor ARGS)
          (begin (set! create-editor-args ARGS) (create-editor))

 - variable+: create-editor-args
     This variable controls the initialization of Edwin.  The following
     values are defined:

    `(#f)'
          This is the default.  Creates a window of some default size,
          and uses that window as Edwin's main window.  Under unix, if
          X11 is not available or if the `DISPLAY' environment variable
          is undefined, Edwin will run on Scheme's console.

    `(x)'
          Unix only.  Creates an X window and uses it as Edwin's main
          window.  This requires the `DISPLAY' environment variable to
          have been set to the appropriate value before Scheme was
          started.

    `(x GEOMETRY)'
          Unix only.  Like `(x)' except that GEOMETRY specifies the
          window's geometry in the usual way.  GEOMETRY must be a
          character string whose contents is an X geometry
          specification.

    `(console)'
          Unix only.  Causes Edwin to run on Scheme's console, or in
          unix terminology, the standard input and output.  If the
          console is not a terminal device, or is not powerful enough
          to run Edwin, an error will be signalled at initialization
          time.

    `(pm)'
          OS/2 only.  Creates a Presentation Manager window and uses it
          as Edwin's main window.

    `(win32)'
          Windows only.  Creates a window and uses it as Edwin's main
          window.