Adding initial work on The Muddle Programming Environment
authorJason Self <j@jxself.org>
Thu, 30 Jun 2016 01:21:57 +0000 (18:21 -0700)
committerJason Self <j@jxself.org>
Thu, 30 Jun 2016 01:21:57 +0000 (18:21 -0700)
md/environment.md [new file with mode: 0644]

diff --git a/md/environment.md b/md/environment.md
new file mode 100644 (file)
index 0000000..b30763e
--- /dev/null
@@ -0,0 +1,1303 @@
+# The Muddle Programming Environment
+
+By P. David Lebling
+
+MIT Technical Report 294
+
+May 1980
+
+Laboratory for Computer Science  
+Massachusetts Institute of Technology  
+545 Technology Square  
+Cambridge, Massachusetts 02139
+
+# Copyright
+
+This book was originally published in the United States in 1980
+without a copyright notice and without subsequent registration with
+the U.S. Copyright Office within 5 years. Doing at least one of those
+[was a requirement of United States copyright law at that
+time](http://copyright.cornell.edu/resources/publicdomain.cfm). This
+book is therefore in the public domain in the United States for
+failure to comply with the required formalities. This means you're
+free to download, modify and redistribute this book. People outside of
+the United States must check the copyright laws of their country
+before downloading or redistributing.
+
+# Introduction
+
+The Muddle language is described in "The Muddle Programming Language",
+but in addition to the language itself, there is a rich and varied
+collection of software written in the language which facilitates the
+writing of programs and systems of programs in Muddle. The information
+describing this programming environment has been contained in various
+documents, some out of print or out of date, and in supplemental disk
+files describing changes and additions. Some of the packages of
+functions used to deal with Muddle code have never been formally
+documented. This manual brings together some of that scattered
+documentation.
+
+The document's purpose is to flesh out the description of the language
+contained in "The Muddle Programming Language", giving a fuller
+description of the program writing and debugging aids available to
+Muddle users, to describe the methods for producing code usable by
+others, to describe the Muddle compiler and the many other techniques
+for producing and speeding up Muddle object code.
+
+The imagined reader of this document is someone who has read "The
+Muddle Programming Language", and now proposes to write programs in
+Muddle, possibly even very large programs. Muddle packages that they
+would find useful in the process of doing so are documented here:
+editors, debuggers, etc. Packages that they might wish to use within
+their program are not included: data-management systems, command
+interpreters, etc.
+
+This document is highly self-referent, as many of the components of
+the Muddle programming environment refer to reach other and adhere to
+the same conventions. Additionally, this document assumes that the
+read is familiar with the language itself (at least to some degree)
+and with the ITS, TENEX, or TOPS-20 operating systems.
+
+# Acknowledgments
+
+The programs described in this document are the products of many years
+of effort by many people. Most have been "touched" by several
+programmers, added to and improved over the years.
+
+Some of the people responsible for the programs mentioned in the
+document are Chris Reeve (Muddle, the compiler, `GLUE`); Brian
+Berkowitz (Muddle, the compiler, `TEMPLATE`, `SUBRFY`); Bruce Daniels
+(Muddle, the compiler, `PACKAGE`, `PPRINT`, `DEBUGR`, `ASSEM`); Tim
+Anderson (`PACKAGE`, the Library, `FINDATOM`, `DFL`, Combat, Mudinq);
+Neal Ryan (`EDIT`, `PDUMP`, the IPC interface); Marc Blank (Mat,
+Muxicom, `MONITR`, Combat, `EDIT`, `CURSOR`); Dave Lebling (`CRITIC`,
+`EDIT`); Michael Broos (the Library); Roger Banks (`TRACE`); Greg
+Pfister (`PPRINT`); Joel Berez (`EDIT`).
+
+Most of the documentation in this manual is from published and
+unpublished memos of the Programming Technology Division of the M.I.T.
+Laboratory for Computer Science. As a general rule, updates and
+revisions to this and other PTD documents concerning Muddle are
+available online in the directory "`MUDMAN`" at MIT-DMS.
+
+# Notation
+
+Anything which is written in the Muddle language or which is typed on
+a computer console appears here in in a typewriter font, as in
+`PPRINT` while a metasyntactic variable -- something to be replaced in
+actual use by something else -- appears as *channel*, in an italic
+font. Where a meta-syntactic variable is being used to denote a
+required argument to some function, it appears as before, but in bold,
+as **channel**.
+
+In the argument templates of Muddle functions, the individual
+arguments are often given in the form *argument:type*, where
+*argument* is a "descriptive" name for the argument, and *type* is its
+Muddle type (or range of types). In such cases, the "type" *boolean*
+indicates an argument that is only examined for truth or falsity, and
+not for any of its other qualities. Such arguments in Muddle are often
+declared `<OR ATOM FALSE>`.
+
+Finally, file names are given as though for the ITS operating system:
+
+    device:sname;fnm1 fnm2
+
+The analogous specification for TENEX or TOPS-20 would be
+
+    device:<sname>fnm1,fnm2
+
+Note that in the TENEX/TOPS-20 version of Muddle, the *fnm2* (which
+may include the *generation* number, *protection* and *account*
+fields) is by default `MUD` as opposed to \> for the ITS version.
+
+# 1\. Overview of the Muddle Programming Environment
+
+The part of the Muddle programming environment described in this
+document are primarily those dealing with the writing, debugging,
+sharing, and maintenance of code and programs written in Muddle. Most
+of the packages described herein are written in Muddle themselves:
+some are assembly language programs useful to Muddle programmers.
+
+The document is divided into chapters dealing with the major issues
+facing the notice (or even the experienced) Muddle programmer:
+
+  - **The Package System** introduces the standard mechanism for
+    lexical blocking and therefore, sharing of Muddle code.
+    Understanding its use is fundamental to writing Muddle programs.
+
+  - **Program Writing And Debugging Aids** is the largest chapter. It
+    covers mechanisms for loading, dumping, editing and debugging
+    Muddle code, whether interpreted or compiled, in a development or
+    production system.
+
+  - **The Library System** discusses the usage of libraries of Muddle
+    programs.
+
+  - **The Compiler** includes the specifics of interaction with the
+    Muddle compiler, as well as an overview of the theory behind its
+    operation.
+
+  - **Making It Run Faster** covers the various methods for speeding
+    up "production" Muddle code by removing mediated calls and
+    compacting data structures.
+
+  - **The Assembler** documents the Muddle assembler and some methods
+    of debugging binary code.
+
+  - **Informational Aids** discusses a few programs, mostly written in
+    assembly language, rather than Muddle, which are useful to the
+    Muddle programmer.
+
+# 2\. The Package System
+
+The portion of the Muddle environment which provides a uniform
+facility for lexical blocking is known as the Package System. In one
+sense it is the most basic part of the environment, since it enables
+many programmers to use each other's code without identifier
+conflicts.
+
+In addition, the Package System is interfaced to a library facility
+(see section 4) by which Muddle code may be stored and later loaded as
+needed.
+
+The Package System is so basic to use of the Muddle environment that
+(with a few exceptions) every subsystem or family of Muddle functions
+described in this document is a "package".
+
+## 2.1. The Theory Of Lexical Blocking In Muddle
+
+Lexical blocking is implemented in Muddle by means of `OBLIST`s and
+`LIST`s of `OBLIST`s. Changes of lexical context are performed using
+the `SUBR`s `BLOCK` and `ENDBLOCK`. The Package System provides a
+high-level interface to these low-level constructs.
+
+The primary goal of a lexical blocking scheme is the prevention of
+identifier conflicts. Specifically, when your program references the
+variable `X`, it should be your `X` and not that of some other
+program. At the same time, it should not be necessary for a programmer
+to search every program previously written to verify that an
+identifier he wishes to use is not already "taken".
+
+It should be clear that the simplest solution, a single `OBLIST`, will
+not satisfy either of these goals. With only one `OBLIST` there would
+necessarily be identifier conflicts, necessitating exhaustive
+searching for unique identifiers.
+
+Obviously, programmers could put their program's identifiers on an
+`OBLIST` unique to that program. Unfortunately, such a solution
+addresses only half the program. What happens when some other
+programmer wishes to use some of this code? He could insert the unique
+`OBLIST` for that program into the `OBLIST` path for his program; but
+the moment that is done he gets all the identifiers for that program,
+including local variable, internal data structures, and so on.
+
+Consequently, we move to a situation where each program uses two
+`OBLIST`s: one for the identifiers that are local to the program, and
+one for the identifiers that are to be used by other programs. In the
+Package System, these are known as the "internal" `OBLIST` and the
+"entry" `OBLIST`.
+
+Most of the identifiers in a program are local to it, and want to be
+placed on the internal `OBLIST`. Therefore, in terms of an argument to
+the `BLOCK` `SUBR`, when a program is being loaded into Muddle, the
+`OBLIST` path wants to be:
+
+( *internal-oblist  
+entry-oblist*  
+`<ROOT>` )
+
+With this `OBLIST` path, most `ATOM`s (identifiers) will be on the
+internal `OBLIST` (as `READ` puts unknown identifiers on `<1
+.OBLIST>`), but the `ATOM`s for the entries and the `ATOM`s for the
+usual `SUBR`s will be available.
+
+The only issue yet to be addressed is that of using an entry of a
+different program in your program. This is accomplished by adding the
+entry `OBLIST` of any such programs to the path after `ROOT`:
+
+( *internal-oblist  
+entry-oblist*  
+`<ROOT>`  
+*other-program-entry-oblist  
+yet-another-program-entry-oblist*  
+.  
+.  
+. )
+
+As only the entry `OBLIST`, and not the internal `OBLIST`, of the
+program being used is added to the path, the chance of identifier
+conflict is lessened.
+
+All that remains is to introduce the functions by which these various
+operations are performed.
+
+## 2.2. Package System Overview
+
+The functions which make up the Package System are:
+
+  - `PACKAGE` - This indicates the start of a package of functions.
+
+  - `ENDPACKAGE` - This indicates the end of the package of functions.
+
+  - `ENTRY` - This indicates an `ATOM` which is to be made available
+    outside the definition of this package of functions. All other
+    `ATOM`s will not be directly available outside the package.
+
+  - `USE` - This indicates a reference by name to another package of
+    functions.
+
+  - `USE-DATUM` - This indicates a reference by name to a data set.
+
+  - `DROP` and `L-UNUSE` - These undo the effects of `USE` and
+    `USE-DATUM`.
+
+These functions are themselves part of a package named `PKG`, which is
+preloaded into Muddle.
+
+### 2.2.1. Sample Package
+
+A sample Muddle `PACKAGE` is given with comments in order to
+demonstrate the usage of these functions.
+
+    <PACKAGE "HOUR-STRING">
+    
+    ;"PACKAGE begins the package called HOUR-STRING."
+    
+    <ENTRY TIME-STRING>
+    
+    ;"The atom TIME-STRING is an entry to this package;
+     it may be referenced by other packages by
+     USEing HOUR-STRING."
+    
+    <USE "DATIME">
+    
+    ;"Indicate that the package DATIME is
+     used within the current package."
+    
+    <DEFINE TIME-STRING ()
+            <STRING <UNPARSE <HOURS>> " o'clock">>
+    
+    ;"Define this little function which returns a string
+     telling the last hour in a strange format."
+    
+    <DEFINE HOURS () <1 <RTIME>>>
+    
+    ;"Define an internal function which is available
+     only within the HOUR-STRING package, since its
+     name is not in any ENTRY statement.
+     Note that this function refers to RTIME,
+     which is an ENTRY in the DATIME package."
+    
+    <ENDPACKAGE>
+    
+    ;"The end of this little demonstration package."
+
+## 2.3. Package
+
+This function delimits the beginning of a package of functions. It
+takes one required argument, a `STRING`, which is the the name of the
+package. This `STRING` uniquely identifies the package within a
+library of packages (see section 4.)
+
+In a `PACKAGE` those `ATOM`s which are specified as entries live in a
+separate `OBLIST` of their own, called the entry `OBLIST`. The `ATOM`
+naming this `OBLIST` is on the `PACKAGE` `OBLIST` and has the same
+name as the package itself. Thus, an entry "X" of a `PACKAGE` "Y"
+would have as its "full-trailer" name: `X!-Y!-PACKAGE!-`.
+
+`PACKAGE` blocks (sets up) the current `OBLIST` path so that the
+`ATOM`s which are internal to the `PACKAGE` fall into an `OBLIST`
+which is not otherwise used. The `ATOM` naming this `OBLIST` is on the
+entry `OBLIST` of the `PACKAGE`, and is by default given a name
+created by putting the character I at the beginning of the `PACKAGE`
+name. An internal `ATOM` "Z" in the `PACKAGE` "Y" previously mentioned
+would have as its "full-trailer" name: `Z!-IY-Y!-PACKAGE!-`.
+
+`PACKAGE` also keeps track of the fact that the particular `PACKAGE`
+named has been defined in this Muddle process by putting its name on
+the `PACKAGE` `OBLIST`.
+
+`<PACKAGE` **name:string**  
+*iname:string  
+size:fix  
+isize:fix*`>`
+
+`PACKAGE` takes three optional arguments in addition to the required
+one (the optional arguments are ignored if *name* is already a
+`PACKAGE`):
+
+  - *iname* is the name of the internal `OBLIST` of the `PACKAGE`; by
+    default is is the name of the `PACKAGE` with the letter "I"
+    prefixed.
+
+  - *size* is the number of buckets in the entry `OBLIST`; by default
+    
+    19. 
+  - *isize* is the number of buckets in the internal `OBLIST`; by
+    default 23.
+
+In addition to `PACKAGE`, there exists the obsolete function
+`RPACKAGE`, documented here only because some programs still use it.
+The difference between them is that the entry `OBLIST` for an
+`RPACKAGE` is the `ROOT` `OBLIST`. The implication of inserting an
+entry into the `ROOT` is that this requires the name of the entry be
+unique over all `PACKAGE`s, because the entry is, in effect, being
+promoted to the status of a `SUBR`. It is (in rare cases) useful to do
+this, but the correct way is with the function `RENTRY` (see section
+2.3.1.)
+
+### 2.3.1. Entry
+
+The `ENTRY` function applied to one or more `ATOM`s declares that
+these `ATOM`s are to be put into the `OBLIST` reserved for entries in
+this particular `PACKAGE`. Only `ATOM`s declared this way will be
+accessible (in the normal course of events) to functions outside this
+`PACKAGE`.
+
+It is possible to place some entries of a `PACKAGE` on the `ROOT`
+`OBLIST` using the function `RENTRY`. It is recommended that instead
+of using `RPACKAGE` in those rare cases where entries must go on the
+`ROOT`, `RENTRY` be used instead.
+
+All `ENTRY` statements should appear immediately after the `PACKAGE`
+or `RPACKAGE` statement. Note: never put a `USE` statement before the
+`ENTRY` statements; if you do, you may get the `ERROR` message
+`ALREADY-USED-ELSEWHERE`, meaning that the name of an entry is
+conflicting with an `ENTRY` in one of the packages you `USE`d. `ENTRY`
+will also give an `ERROR` if it is used outside the body of a
+`PACKAGE`.
+
+### 2.3.2. USE
+
+This function takes as arguments one or more `STRING`s which are the
+names (as given to `PACKAGE`) of other `PACKAGE`s. `EXTERNAL` is a
+synonym of `USE`. `USE` causes the entry `OBLIST`s of the `PACKAGE`s
+named to be spliced into the current `OBLIST` path. Thus, references
+to entries of those `PACKAGE`s may be made after the `USE`, until the
+next `ENDPACKAGE` (or the next `DROP` or `L-UNUSE` if `USE` is being
+invoked outside a `PACKAGE` to load a file.)
+
+`USE` is consequently the mechanism for sharing code. If the `PACKAGE`
+being used is already loaded, its entries are made available; if not,
+the `PACKAGE` is loaded first (see section 4.1 for details on how this
+is accomplished.)
+
+### 2.3.3. USE-DATUM
+
+`USE-DATUM` requires one `STRING` argument, the name of a data set. If
+the data set is not loaded, `USE-DATUM` loads it and creates an `ATOM`
+of the same name, on the `USE-DATUM` `OBLIST`, whose `GVAL` is the
+data set. `USE-DATUM` always `EVAL`s to the data set named, regardless
+of whether it had to be loaded or not.
+
+### 2.3.4. DROP and L-UNUSE
+
+These function take the same arguments as `USE` and `USE-DATUM` and
+undo their effects.
+
+`DROP` simply splices the named packages out of the current `OBLIST`
+path. A `USE` of a `DROP`ped `PACKAGE` will not reload the `PACKAGE`
+but simply splice it back into the `OBLIST` path.
+
+`L-UNUSE` splices the `PACKAGE` out and removes its name from the
+`PACKAGE` `OBLIST`, which will cause the entire `PACKAGE` to be
+reloaded if it is `USE`d again. `L-UNUSED` of a data set will remove
+its `ATOM` from the `USE-DATUM` `OBLIST`.
+
+### 2.3.5. ENDPACKAGE
+
+The `ENDPACKAGE` function of no arguments terminates the definition of
+the current `PACKAGE` and undoes the lexical blocking done by the
+`PACKAGE` function. The `ENDPACKAGE` statement should be the last one
+in the file.
+
+### 2.3.6. PACKAGE Restrictions
+
+There are some restrictions on what the user may do inside a
+`PACKAGE`. These are enforced by the Library System when the user
+attempts to submit a `PACKAGE` to a library.
+
+A `PACKAGE` should not `FLOAD` or `LOAD` any file to obtain parts of
+itself. All such environment setup should be done with `USE` and
+`USE-DATUM`.
+
+A `PACKAGE` may not reference any `ATOM` whose `OBLIST` path goes
+through the `INITIAL` `OBLIST`. All of the non-entry `ATOM`s in a
+package should fall naturally into it's internal `OBLIST`.
+
+As mentioned before, the `RENTRY` of a package have the same `OBLIST`
+status as `SUBR`s, i.e., they must be unique among both all `SUBR`s
+and all `PACKAGE` entries.
+
+### 2.3.7. ENTRY Name Conflicts
+
+It is possible to have two or more `PACKAGE`s (not `RPACKAGE`s) which
+have entries (not `RENTRY`s) with the same `PNAME`. If the user needs
+both `PACKAGE`s at the same time, he may `USE` them both and refer to
+the ambiguous entries by their "full trailer" names. All of the
+non-ambiguous entries in `PACKAGE`s may still be referenced by `PNAME`
+only.
+
+# 3\. Program Writing and Debugging Aids
+
+This chapter concentrates on editing and debugging aids for Muddle
+programming. The basis for editing and debugging in Muddle is twofold:
+First, Muddle is an interpreter, which permits interactive testing and
+debugging of software. Second, Muddle programs (even compiled Muddle
+programs) are structures and therefore may be manipulated by other
+Muddle programs.
+
+Packages useful in editing and debugging range from `EDIT` and
+`PPRINT`, which are preloaded, and which form the core of most editing
+or debugging systems, to more sophisticated aids such as `DEBUGR` and
+`TRACE`, which are more powerful, and useful for more complicated
+debugging.
+
+It should be noted that, in addition to the editors discussed below,
+RMODE and EMACS, TECO based text editors, understand much of the
+syntax and many of the conventions of Muddle programs.
+
+## 3.1. Pretty-Printing
+
+The purpose of pretty printing is to clarify the structure of Muddle
+objects by printing them in a more human-readable format than that
+provided by the `SUBR`s `PRINT`, `PRIN1`, etc. Objects are
+pretty-printed through the judicious insertion of spaces, tabs, and
+new-lines between tokens. Pretty-printed objects are readable by the
+Muddle Reader. Pretty printing is an aid to understanding and
+debugging Muddle `FUNCTION`s or other objects. You will probably find
+pretty printing to be extremely helpful, especially if you are working
+without a listing or with an old listing. In fact, pretty-printing is
+one way to make a new pretty listing after editing. `PPRINT` is
+pre-loaded in most initial Muddles. The name of the package containing
+`PPRINT` is "`PP`".
+
+`<PPRINT` **any** *channel*`>`
+
+pretty-prints *any* on *channel*. The second argument is option, by
+default `.OUTCHAN`. If *any* is an `ATOM`, `PPRINT` will enclose it in
+an application of `DEFINE`, `DEFMAC`, `SETG`, or `SET`, as seems
+appropriate. `COMMENT`s found inside *any* are right-justified.
+`PPRINT` cannot output an `RSUBR` without `FIXUP`s (that is, one that
+was `READ` in while `KEEP-FIXUPS` (see section 3.4) had no `LVAL` or
+had a `FALSE` `LVAL`); it will give the `ERROR` message
+`CAN-NOT-BE-DUMPED`. `PPRINT` returns `.NULL` which is an `ATOM` whose
+`PNAME` is a single rubout, invisible on most consoles.
+
+`<PPRINF` **in:string-or-atom-or-list** *outfile:string  
+width:fix eval?:boolean*`>`
+
+pretty-prints all the contents of *in* into *outfile*.
+
+If *in* is an `ATOM` or a `LIST` of `ATOM`s, its `VALUE`(s) are the
+objects to be `PPRINT`ed. In this case, *outfile* is by default a file
+whose first name is produced by taking the `PNAME` of *in* (or *in*'s
+first element, if *in* is a `LIST`).
+
+If *in* is a `STRING`, it specifies a file containing objects to
+`PPRINT`. In this case, *outfile* is by default "`TPL:`".
+
+*width* is the maximum width of output lines (although output lines
+are prevented from being extremely long); it is optional, and by
+default `<13 ,OUTCHAN>`.
+
+*eval?* tells `PPRINF` whether or not to `EVAL` everything in the
+file; it is optional, by default a `FALSE` (don't `EVAL`). *eval?* is
+meaningless if *in* is not a `STRING`.
+
+`PPRINF` returns either "`DONE`" or a `FALSE` if it couldn't open
+*infile* or \*outfile(. `PPRINF` inserts page boundaries in *outfile*,
+between objects, every 60 lines or fewer; you may want to move these
+afterward to more logical places. `PPRINF` binds `KEEP-FIXUPS` and
+`REDEFINE` to `T`, and `QUICKPRINT` (see below) to a `FALSE`.
+
+### 3.1.1. PPRINT Control Switches
+
+`PPRINT`'s output is affected by the local values of several `ATOM`s.
+Each value is examined only for truth.
+
+    .QUICKPRINT
+
+If this `ATOM`'s `LVAL` is `FALSE`, you are in slow mode; otherwise
+(include the case of no `LVAL`), you are in fast mode. The behavioral
+difference is this: in fast mode, there may be `COMMENT`s in the
+pretty-printed object(s) which `PPRINT` misses. Also, fast mode is
+indeed faster than slow mode. Fast mode is the default, that is,
+`QUICKPRINT` is initially true. The modes are really distinguished by
+the depth of recursion to which PPRINT resorts. In slow mode, it
+recurses all the way down to every monad in the thing pretty-printed;
+in fast mode, it goes down only far enough to find something that will
+fit on a line.
+
+    .LOOKAHEAD
+
+`PPRINT` uses full recursive lookahead to avoid packing things against
+the right margin and, as a result, not being able to fit things within
+the right margin. The lookahead results in very good formatting of
+deeply-nested `MAPF`ed and `FUNCTION`s; all but the most bizarre cases
+should be very legible. However, it can result in noticeable "pauses"
+in the printing operation and, in some cases, a net speed slightly
+less than with limited lookahead. Since this can be a disadvantage
+when using `PPRINT` interactively on a heavily-loaded system, the
+lookahead can be disabled: if the `LVAL` of `LOOKAHEAD` is a `FALSE`,
+no lookahead will be performed; otherwise it happens. `LOOKAHEAD` is
+initially true, that is, lookahead happens by default.
+
+    .VERTICAL
+
+If `LOOKAHEAD` is a `FALSE`, the formatting can cause too many objects
+to be squeezed against the right margin. So that particular cases can
+be made legible, the format when lookahead is not in use can be
+manually set: if the `LVAL` of `VERTICAL` is non-`FALSE`, `PPRINT`
+will indent very little whenever indenting is called for. (`VERTICAL`
+being true means a "more vertical" format.) `VERTICAL` is initially
+`FALSE`. The value of `VERTICAL` is ignored when `LOOKAHEAD` is true;
+the lookahead effective chooses different values for `VERTICAL` for
+different parts of the object pretty-printed.
+
+### 3.1.2. Lower-level Pretty Printing
+
+It is sometimes desirable to use some of the functions that `PPRINT`
+uses but in a different way. For example, a specialized pretty-printer
+for Program Abstracts would want to insert indented field names into
+the output and pretty-print field values with the same indentation.
+The names of lower-level pretty-print functions are included in the
+`ROOT` `OBLIST` for such purposes.
+
+`<EPRINT` **any** *left-margin:fix*`>`
+
+pretty-prints *any* on `.OUTCHAN` to the right of *left-margin*. The
+second argument is optional, by default `<VALUE LEFT-MARGIN>` (see
+below.)
+
+`<EPRINT` **any** *left-margin:fix*`>`
+
+`EPRIN1` is to `EPRINT` as `PRIN1` is to `PRINT`.
+
+    .LEFT-MARGIN
+
+This is the `ATOM` that `EPRINT` binds to its second argument. You can
+`SET` it outside calls to `EPRINT` in order to make a permanent left
+margin. Its initial `LVAL` IS 0.
+
+`<INDENT-TO` **column:fix** *channel*`>`
+
+outputs tabs and/or spaces to advance the output column (`<14
+channel>`) to *column*, if it is not already past.
+
+`<COLPP` **any**  
+*channel  
+left-margin:fix  
+right-margin:fix*`>`
+
+pretty-prints *any* on *channel* (by default `.OUTCHAN`) between the
+margin *left-margin* (by default `<14 channel>`, the current column)
+and *right-margin* \*by default `<13 channel>`, the rightmost column.)
+All arguments but the first are optional. `COLPP` returns `,NULL`. For
+example, `<COLPP any .OUTCHAN 10 70>` would leave a 10-character
+margin at left and right on an 80-column `OUTCHAN`. Also,
+
+    <PRINT () PRINT AAAAAAAAAAAAAAA> <COLPP ,FOO>>
+
+would result in output like
+
+    AAAAAAAAAAAAAAA #FUNCTION ((X GGGGGGGGGGGGGGGGGGGGGG)
+                              <+ X 1>)
+
+`EPRINT`, `EPRIN1`, and `COLPP` are affected by the truth of
+`.QUICKPRINT`, `.LOOKAHEAD`, AND `.VERTICAL`.
+
+### 3.1.3. Ampersand Printing
+
+"Ampersand printing" consists of printing any object on a single line
+by using the character `&` (ampersand) to mean "There's more stuff
+here." (This technique is borrowed by the InterLisp editor.)
+
+There are two ways in which `&` is used by this printer as an
+abbreviation:
+
+1.  An `&` appearing between some variety of brackets indicates that
+    there is a big object of the indicated `TYPE` there.
+2.  The characters `..&` or `&..` on the left or right of a structure
+    mean that there are more objects to the left or right which have
+    not been printed.
+
+Example:
+
+    #FUNCTION ((A B C D) <&>)
+
+This is a `FUNCTION` with four arguments in its argument `LIST`, and
+the `FUNCTION` body contains one `FORM` which was too big to print in
+the remainder of the line.
+
+    <PROG () <KRK <+ /A 5>> <PRINC .Q> <SET BAR <ORG>> <&> &..>
+
+This is a large `FORM`, namely a `PROG`. In addition to the elements
+printed, there are more elements to the right, and there is one `FORM`
+which was too big to print.
+
+Ampersand printing is effected by two pure `RSUBR`s: `&`, analogous to
+`PRINT`, and `&1`, analogous to `PRIN1`. A related `RSUBR`, `&LIS`,
+can be applied to no arguments to put you into an endless
+`READ-EVAL-&` loop, instead of the normal `READ-EVAL-PRINT` loop.
+
+### 3.1.4. Examining the stack
+
+`<FRM` **fix**`>`
+
+returns the *fix*th `FRAME` down from the top application of `ERROR`
+or `LISTEN`.
+
+`<FRAMES` *how-many:fix start:fix*`>`
+
+pretty-prints *how-many* `FRAME`s (by printing the `FRAME` number
+(suitable as an argument to `FRM`), `FUNCT`, and `ARGS` of the
+`FRAME`), starting with `<FRM` *start*`>`. Both arguments are
+optional; *start* defaults to 0, and *how-many* defaults to a large
+integer. A `FRAME` whose `FUNCT` is an `ATOM` whose `VALUE` is an
+`FSUBR` is not printed, if the same information is found in the next
+lower `FRAME`.
+
+`<FR&` *how-many:fix start:fix*`>`
+
+is like `FRAMES but uses ampersand printing instead of pretty
+printing. It is handy for summarizing`FUNCT`s and`ARGS`that are large
+or unprintable (like`RSUBR\`s with no fixups).
+
+`<FRATM` *how-many:fix start:fix*`>`
+
+is like `FRAMES` but gives an abbreviated view of the stack. It prints
+`FUNCT`s only, and only for `FRAME`s connected with named `FUNCTION`s,
+`RSUBR`s, and `RSUBR-ENTRY`s. It is handy when a `FRAME` contains a
+non-`LEGAL?` object.
+
+`<FRLVAL` **atom**  
+*how-many:fix  
+start:fix*`>`
+
+prints out the stacked bindings of *atom*, going through *how-many*
+`FRAME`s, starting with `<FRM` *start*`>`. The two numeric arguments
+are optional; *how-many* defaults to a large integer, and *start*
+defaults to 0. The format of the printing is two columns: the first
+column is the number of the `FRAME` in which *atom* has a binding; the
+second column is the value bound, or a message proclaiming the lack of
+a value.
+
+`<FR&VAL **atom**\ *how-many:fix\ start:fix*`\>\`
+
+is precisely the same as FRLVAL, except that the values are ampersand
+printed instead of `PRINT`ed.
+
+Finally, the "`FRMSP`" `PACKAGE` contains analogues of many of the
+preceding functions, but each takes as its first argument a `PROCESS`,
+by default `<ME>`. These are all named by adding a 'P' to the end of
+the usual name. For example,
+
+    <FR&P <MAIN>>
+
+Does does a `<FR&>` in the `PROCESS` `MAIN`.
+
+There is one additional function of interest in "FRMSP".
+
+`<FRTYPE` *how-many:fix start:fix*`>`
+
+is like `FRAMES`, but gives only the `TYPE`s of the arguments to each.
+This is useful in those situations when the stack shows illegal
+`FRAME`s or other unprintable objects.
+
+## 3.2. The Muddle Editor
+
+`EDIT` allows a Muddle user to make incremental changes in Muddle
+structured objects, without leaving Muddle and with the ability to
+save the results in a file, and to set or clear conditional
+breakpoints of various sorts in objects that will be evaluated, such
+as `FUNCTION`s.
+
+`EDIT` is an editor/debugger written in, written for, and running
+under Muddle. It comprises the package "`EDIT`" and several smaller
+packages which wi11 be mentioned later in this section. `EDIT` is
+preloaded in most initial Muddles.
+
+To start editing, apply `EDIT` to no arguments or to the name of the
+object you wish to edit: `<EDIT>` causes entry into `EDIT` and opens
+the last object edited; `<EDIT` *object*`>` causes entry into `EDIT`
+and opens *object* for editing. Permissible *object*s include:
+
+  - `ATOM`s. The `GVAL` (preferably) or the `LVAL` of the `ATOM` is
+    opened. If it has no value, `EDIT` returns a `FALSE`.
+
+  - A `PRIMTYPE` `LIST`. The `PRIMTYPE` `LIST` is opened.
+
+  - A `FIX`. The stack frame with that number is opened (i.e., `<ARGS
+    <FRM` *fix*`>>`).
+
+Part of `EDIT`'s efficiency comes from forbidding it to delve into
+objects that are not of `PRIMTYPE` `LIST`, that is, not `LIST`s,
+`FORM`s, `FUNCTION`s, etc. Attempts to edit objects of other
+`PRIMTYPE`s will result in error messages. These objects can, however.
+be treated as units when inserting. searching, etc.; or they can be
+changed into `LIST`s, edited, and then changed back to their original
+types.
+
+### 3.2.1. The Edit 'LISTEN Loop'
+
+#### 3.2.1.1. The Reader
+
+When in `EDIT`, you are typing at a special, non-standard, input
+function: The `EDIT` Reader.
+
+The Reader allows you to type `EDIT` commands and have them executed,
+and also to evaluate Muddle expressions normally. Its characteristics
+are as follows:
+
+  - As in the normal Muddle Reader, nothing is done until you type
+    `ESC`. `DEL`, `Ctrl-L`, `Ctrl-D`, `Ctrl-G`, and `Ctrl-S` also work
+    normally.
+
+  - All `EDIT` commands are terminated when an `ESC` is encountered in
+    the input stream. (In addition. most commands will terminate
+    whenever the maximum number of arguments required has been input
+    or whenever an argument of the wrong type is encountered. In the
+    former case the next object is taken as a new command; in the
+    latter case the object of the wrong type is taken as a new
+    command. `EDIT` commands may be typed in either upper or
+    lowercase.
+
+  - If you type something that `EDIT` does not recognize as a command,
+    normal Muddle evaluation and printing are performed on that
+    something. This evaluation will have no effect on your position in
+    the object you are editing.
+
+  - While editing a function which is part of a `PACKAGE` (determined
+    from an examination of the `OBLIST` containing the `ATOM` whose
+    value is the function), `EDIT` causes the OBLIST path to be set up
+    to what it was in the environment of that `PACKAGE`. This has the
+    advantage of reducing the number of trailers printed, and causes
+    newly entered `ATOM`s to fall on the correct `OBLIST` (the
+    internal `OBLIST` of the `PACKAGE`). It has the slight
+    disadvantage that it disables the dynamic loader (which depends on
+    unbound variables falling on the `INITIAL` `OBLIST`). If the
+    `GVAL` of `E-PKG` is a `FALSE`, this feature is disabled, and the
+    normal `OBLIST` path is in effect during editing.
+
+Examples:
+
+    R 5$
+
+Causes execution of `EDIT` command R with argument 5.
+
+    <R 5>$
+
+Causes application of the function R to 5.
+
+#### 3.2.1.2. The Ampersand Printer
+
+Your current position is displayed by "ampersand printing' (see
+section 3.1.3). This consists of printing any object on a single line
+by using the character & (ampersand) to mean "There's more stuff
+here."
+
+The ampersand printer used in `EDIT` is much like the standard one,
+with the addition that your current position (see below) is displayed
+by the glyph of a solid square: &block;.
+
+When you initially enter `EDIT`, you are in a mode called
+"non-verbose", in which ampersand printing is not automatically done
+following execution of `EDIT` commands. The `V` command is used to
+toggle you in and out of verbose mode (see below).
+
+Examples:
+
+`<FUNCTION (` &block; `(A B C D) <&>>`
+
+Indicates that your position is just to the left of a `FUNCTION`'s
+argument list. and the `FUNCTION` body contains one `FORM` which was
+too big to print.
+
+`<..& <KRK <+A .A 5>>` &block; `<SET BAR <ORG>> <&> *..>`
+
+Indicates that you are in the middle of a large `FORM` (e.g., a
+`REPEAT` or a `PROG`), positioned just to the left of the `<SET BAR
+<ORG>>`. In addition to the objects printed, there are more objects to
+both the left and the right, and there is one `FORM` which was too
+large to fit on the line.
+
+### 3.2.2. Edit Commands
+
+#### 3.2.2.1. General
+
+A sequence of `EDIT` commands is executed as soon as you type `ESC`.
+If one command fails, subsequent commands up to the `ESC` are ignored,
+and EDIT types out an appropriate error message. A failing
+`EDIT`command generally has no effect whatsoever; but see individual
+descriptions.
+
+Note that *all* arguments to `EDIT` functions must be legal Muddle
+objects. In particular, you can't search for `<SET`, since the `<>`'s
+aren't balanced. Nor can you insert it. (But you can, for instance,
+search for and insert `<SET THING 1>`.)
+
+If a command expects an argument and doesn't get one, an error message
+will be printed.
+
+Many `EDIT` commands take `FIX`es as arguments. Those that do
+interpret the `ATOM` \* as an argument to mean "as many as possible".
+
+Whenever you are in `EDIT`, you have a well-defined "position". A
+position is a "place" *inside* a Muddle structure: this "place" is
+either *between* two elements elements of the structure, or between an
+element and either end of the structure, or *inside* an empty
+structure. All editing, movement, and printing commands operate
+relative to your current position. The term "cursor" is used in the
+following descriptions to refer to an embodiment of a position.
+
+The format listed in each of the following command descriptions is:
+
+Command as Typed  
+English Name  
+Description
+
+#### 3.2.2.2. General Commands
+
+`?`  
+`duh?`  
+Causes a short summary of all EDIT commands to be typed out. The same
+summary appears later in this chapter.
+
+`??`  
+`huh?`  
+Similar to the above, but the summary is even shorter, and should fit
+entirely on the screen of an Imlac terminal.
+
+`Q`  
+`Quit`  
+Leave `EDIT` and return to Muddle. (Causes `EDIT` to return the `ATOM`
+`T`.)
+
+`QR` *fix*  
+`Quit and Retry`  
+Quit from `EDIT` and then retry the frame specified, or by default,
+the one originally given to an open command or, if none was given, the
+frame beneath the last `ERROR` or `LISTEN` frame.
+
+`Ctrl-F`  
+`Control-F`  
+This is not really an `EDIT` command; rather, it is a character,
+obtained from the input stream at interrupt level, which is used to
+return you to the `EDIT` Reader from some higher level of application,
+e.g., an `ERROR`'s `LISTEN`. It is the `EDIT` equivalent of `ERRET`
+with no arguments.
+
+`Ctrl-F` (or `Ctrl-S`) typed during execution of an `EDIT` command is
+similar to normal Muddle `Ctrl-S` but returns to the `EDIT` Reader
+instead of the Muddle `LISTEN` loop.
+
+`O` **object**  
+`Open`  
+Equivalent to `Q` followed by `<EDIT` *object*`>`. Positions the
+cursor just to the left of the first element of the entire object
+specified.
+
+`OT`  
+`Open This`  
+If the object to the right of the cursor is an `ATOM`, or a `FORM`
+whose first element `ATOM`, and the `ATOM`'s value is openable, then
+it is opened. This command is useful when tracing a calling sequence
+through several functions.
+
+#### 3.2.2.3. Movement Commands
+
+`UT`  
+`Up to the Top`  
+Places the cursor at the position it had following an `O`.
+
+`R` *fix*  
+`Right`  
+Moves the cursor *fix* objects to the right, by default one. If *fix*
+is too large, i.e., there are not that many positions to the right of
+the current position, `EDIT` prints an error comment and the cursor
+stays where it is.
+
+`B`  
+`Back`  
+Moves the cursor as far to the right as possible.
+
+`L` *fix*  
+`Left`  
+Moves the cursor \*fix( positions to the left, by default one. If
+*fix* is too large, EDIT prints an error message.
+
+`F`  
+`Front`  
+Moves the cursor as far to the left as possible.
+
+`DL`  
+`Down Left`  
+Positions the cursor just to the right of the rightmost element within
+the object to the left of the cursor, if that object is of `PRIMETYPE`
+`LIST`. Visually, the cursor moves left over one "close bracket".
+
+`DR`  
+`Down Right`  
+Positions the cursor just to the left of the leftmost element within
+the object to the right of the cursor, if that object is of `PRIMTYPE`
+`LIST`. Visually. the cursor moves right over one "open bracket". If
+the cursor is to the left of an element that is not of `PRIMETYPE`
+`LIST`, `EDIT` prints an error message.
+
+`D`  
+`Down`  
+Equivalent to `DR`.
+
+`UR` *fix*  
+`Up Right`  
+Positions the cursor just to the right of the object the cursor is
+currently within. Does so `fix` times, by default once.
+
+`UL` *fix*  
+`Up Left`  
+Positions the cursor just to the left of the object the cursor is
+currently within. Does so *fix* times, by default once.
+
+`U` *fix*  
+`Up`  
+Identical to `UL`.
+
+`S` *object*  
+Search  
+Does a depth-first, left-first tree-walk. (i.e., left-to-right)
+starting with the object to the right of the cursor. until the cursor
+is just to the right of an object structurally equal (i.e., =?) to its
+argument. An occurrence of the object will not be found if it is
+inside anything not of `PRIMETYPE` `LIST`. On failure. the cursor does
+not move. If the argument is omitted, the last object searched for is
+used.
+
+`SR` *object*  
+`Search Right`  
+Same as `S`.
+
+`SL` *object*  
+`Search Left`  
+Same as `S`, but the tree-walk is depth-first, right-first (i.e.,
+right-to-left) and you end up to the left of the object for which you
+were searching.
+
+#### 3.2.2.4. Printing Commands
+
+`The Empty Command`  
+Causes the normal "ampersand print" to be done. This is principally
+useful when you are in "silent" mode; see the `V` command.
+
+By the way, an "empty" command is typed by typing `ESC` without having
+typed any visible characters before it.
+
+`P`  
+`Print`  
+`PPRINT`s (not "ampersand prints") the object to the right of the
+cursor.
+
+`PU`  
+`Print Up`  
+`PPRINT`s the object the cursor is in. This is similar to doing a `U`
+and then a `P`, although the cursor is not moved.
+
+`PT`  
+`Print Top`  
+`PPRINT`s the whole object you have open.
+
+`V`  
+`Verbosity`  
+Toggles the verbosity mode between "verbose" (most commands cause
+ampersand printing) and "silent" (printing of any sort is done only
+when some explicit print command is used, or when an error occurs.)
+The current state of verbosity is the `G-VAL` of `E-VERBOSE`.
+
+In silent mode, absolutely *nothing* is printed after each command,
+not even new-lines or prompts. However, normal Muddle evaluation still
+causes normal Muddle printing.
+
+#### 3.2.2.5 Editing Commands
+
+`I` **any** ...  
+`Insert`  
+Inserts all its arguments immediately to the right of the cursor. None
+of its arguments are evaluated; you can insert unevaluated `FORM`s
+without using `QUOTE`. The cursor ends up to the right of the last
+object inserted.
+
+`G` **any** ...  
+`Get`  
+Same as `I`, but its arguments are evaluated. This is useful in
+conjunction with the `X` command (see below.)
+
+`I:` *type:atom fix*  
+`Insert Type`  
+Grabs *fix* objects to the right of the cursor, inserts them into a
+newly created object of `TYPE` *type*, deletes them from the original
+structure, and inserts the newly created object in their place. In
+other words, it "inserts" the appropriate open and close brackets for
+*type* at the cursor and *fix* objects to the right.
+
+By default *fix* is one, *type* is `LIST`. An error message is printed
+if *fix* is larger than the number of objects to the right of the
+cursor.
+
+There is no way to directly insert or delete single parentheses,
+brackets, etc. using `EDIT`. Insert, use `K:` (see below) to remove
+pairs of brackets, and `I:` to insert them.
+
+`I*` *indicator:atom* **new-structure**  
+`Imbed`  
+Imbed looks for all occurrences of *indicator* in *new-structure* and
+replaces these occurrences with objects taken and deleted from the
+right of the cursor. In then inserts the result.
+
+If only *new-structure* is given, the *indicator* is the `ATOM` \*. If
+there aren't enough objects to the right of the cursor to replace each
+`indicator`, remaining indicators are left untouched and a warning
+message is printed.
+
+`I*` is generally used to insert one or more structures into another
+complex structure in one operation, instead of several. For example:
+
+`<SET X` &block; `<12 .Y>>`  
+`I* <COND (<NOT <LENGTH? .Y 11>> *)>$`  
+`<SET X <COND (<NOT <LENGTH? .Y 11>> <12 .Y>)>` &block; `>`
+
+Places a protective conditional around an `NTH` to prevent an
+out-of-bounds error.
+
+`IG` **any** ...  
+`Insert Into Group`  
+Insert into a group. `IG` is similar to `I`, but assumes that the
+object you are in is a group (as produced by `GROUP-LOAD`). Arguments
+to `IG` which are not `ATOM`s are inserted as `I`, Objects which are
+`ATOM`s and which have a value insert a `FORM` which `DEFINE`s,
+`SETG`s, or `SET`s the `ATOM` as appropriate. Thus, to add a new
+function `F` to a group \`G1 one could type:
+
+    O G$IG F$Q$
+
+`K` *fix*  
+`Kill`  
+Deletes `fix` objects to the right of the cursor. Defaults to one.
+Negative `fix` causes deletion to the left of the cursor.
+
+`C` **any**  
+`Change`  
+Changes the one object to the right of the cursor so its single
+argument. Does not move the cursor. Does not evaluate is argument. `C`
+is more efficient than `K` plus `I`.
+
+`C:` **type:atom**  
+`Change Type`  
+Changes the type of object to the right of the cursor to *type*.
+Attempts to do something reasonable for every type change. If you tell
+it to change a `STRING` to a`LIST`, you get a `LIST` of `CHARACTER`s.
+If you attempt to change a structure whose elements are other than
+`CHARACTER`s and `STRING`s to a `STRING`, you will get a Muddle error.
+
+`K:`  
+`Kill Type`  
+Deletes the brackets around the object to the right of the cursor i.e.
+kills the object and inserts its elements into the structure of which
+it was a part.
+
+`SU` **new** **old**  
+`Substitute`  
+The Substitute command takes two arguments. All occurrences of *old*
+from the current location to the end of the open object (actually a
+search-right is done) are replaced by *new*. Once the search for *old*
+fails, the command terminates, and the number of substitutions
+performed is printed. The cursor is left after the last object
+replaced.
+
+`X` **atom**  
+`Transfer`  
+`SET`s the *atom* to the object to the right of the cursor. `X` can be
+used with `K` and `G` to move things around within the object being
+edited.
+
+`SW`  
+`Swap`  
+Swaps the two objects to right of the cursor, leaving the cursor
+pointing at the same object. The effect is to move the cursor and the
+object it points at one object to the right. Repeated `SW`s move
+cursor and object further and further to the right.
+
+#### 3.2.2.6. Macro Facility
+
+`M` **macro**  
+`Macro`  
+Takes either a `STRING` or something which `EVAL`s to a `STRING` and
+performs all of the commands in the `STRING`. For complete assurance
+that your commands will be done properly, put an ESC between commands.
+
+`IT` **fix** *macro*  
+Iterate  
+This command (also called DO) takes a *fix* and macro as if an
+argument to `M`. This command will loop through the *macro* *fix*
+times or until an error is generated. When the iteration ends, the
+user is told how many complete passes have been made of the `macro`.
+
+In both of the above commands, if an `EDIT` error is generated, the
+*macro* will be terminated, and the *macro* itself will be printed,
+with an arrow pointing to the offending command. The cursor wilt
+remain at the place where the last legal command left it.
+
+The SU command is, internally:  
+`DO * "S` *old*`$L$C` *new*`$"`
+
+#### 3.2.2.7. Cursors
+
+Cursors are locations in objects being `EDIT`ed. In addition to the
+main cursor, which is where editing occurs, other locations (also
+called cursors) may be remembered. The main cursor may be moved to
+another cursor in a single operation, potentially saving many motion
+commands. In large `FUNCTION`s cursors may also reduce confusion by
+distinguishing among several similar areas of code.
+
+`UC`  
+`Use Cursors`  
+The `PACKAGE` for dealing with cursors is not normally loaded in an
+initial Muddle, so the UC command loads it and makes the cursor
+commands available. The `PACKAGE` loaded is "`CURSOR`".
+
+`CU` *atom*  
+`Cursor`  
+`CU` takes an `ATOM` argument and `SET`s the `ATOM` to an object of
+type `CURSOR`, which tries to be clever in the event you change the
+object. Also, if you use the `X` command to name a substructure and
+then move copy it with `G` or `I`, the cursors in the substructure
+will follow to the new location.
+
+There are some restrictions. Cursors in empty `LIST`s are okay but
+they will not follow the object to new locations. Also this
+"following" feature is effective only at the first `G` or `I` after
+the `X`. To move the substructure again you have to `X` again.
+
+`I*` is somewhat incompatible with `CURSOR`s. Cursors in Imbedded
+structures will sometimes disappear.
+
+`GO` **cursor** `Go` `GO` takes a *cursor* (normally the `LVAL` of an
+`ATOM` previously given as an argument to `CU`) and `GO`es to that
+position. If the *cursor* is illegal (not in the current top-level
+structure), an error message will be printed and you will remain in
+your previous position.
+
+`KC` **atom**  
+`Kill Cursor`  
+Kill the cursor assigned to *atom*.
+
+`PC`  
+`Print Cursors`  
+Prints all cursors in the structure to the right of the main cursor.
+
+`PA`  
+Prints all cursors in the currently open structure.
+
+#### 3.2.2.8. Breakpoints
+
+`BK` *predicate* *any* ...  
+`Breakpoint`  
+Inserts a breakpoint "around" the object to the right of the cursor.
+Takes any number of arguments. Subsequently, whenever that object
+would have heen evaluated, you instead hit a breakpoint function
+which:
+
+1.  Evaluates *predicate*. If the value is `FALSE`, evaluation
+    continues as if there were no breakpoint. If the value is
+    non-`FALSE`, or `BK` was given no arguments:
+
+2.  Types `**BREAK**`.
+
+3.  For each argument after the first that you gave `BK`, types
+
+*arg = EVAL of arg*
+
+4.  Enters `LISTEN`.
+
+You continue by applying `ERRET` to one argument, just as from an
+`ERROR`; the argument's value is ignored.
+
+Breakpoints are implemented by inserting a `BREAKR` (a `PRIMTYPE`
+`LIST` with `APPLYTYPE` `FORM`) which consists of the function
+`BREAKR` and arguments, including the object breakpointed. A
+breakpoint prints as a glyph similar to the cursor:
+
+<strike>`B`</strike> *object*
+
+If the `ATOM` `SHORT-PRINT` is assigned `FALSE`, the actual `BREAKR`
+`LIST` is printed.
+
+The breakpoint function returns `EVAL` of the thing it is put
+"around", and there are cases where this does not work. There are
+always equivalent places that do work.
+
+1.  Breakpoint on the first element of a `FORM` does not work. Put it
+    on the whole `FORM`.
+
+2.  Breakpoint on a `LIST` which is an argument to a `COND` does not
+    work. Put it on the first `FORM` in the `LIST`.
+
+`BA` *predicate* *any*  
+`Break After`  
+Similar to `BK`, but puts the breakpoint *after* the object at the
+cursor. Its action is like that of `BK` except that the break occurs
+after the object it is on is `EVAL`ed.
+
+This sort of breakpoint prints like the "before" sort. but with the
+glyph after the object broken:
+
+object <strike>`B`</strike>
+
+The *predicate* for a `BA` breakpoint may check the value returned by
+`EVAL` for the object the hreakpoint is on. This value is assigned by
+`BREAKR` to the `ATOM` `VALUE`.
+
+`KT`  
+`Kill This`  
+Removes the breakpoint (if any) from the object to the right of the
+cursor.
+
+`KB`  
+`Kill Breakpoints`  
+Removes all breakpoints in the currently open object.
+
+#### 3.2.2.9. Edit Monitors
+
+There are several commands in `EDIT` which provide a simple interface
+to the "`MONITOR`" `PACKAGE`. These allow placing of monitors on
+references to or modifications of `LVAL`s in interpreted Muddle code.
+
+For a more complete discussion of the use of monitors, see section
+3.7.
+
+`UM`  
+`Use Monitors`  
+The `PACKAGE`s for dealing with monitors are not normally loaded in an
+initial Muddle, so the `UM` command loads them and makes the three
+commands for creating monitors available. The `PACKAGE`s loaded are
+"`MONITR`", which is the general monitor `PACKAGE`, and "`EMONIT`",
+which is the interface between `EDIT` and "`MONITR`".
+
+`RW` **atom** *predicate* *any* ...  
+`Read-write Monitor`  
+The most general type of monitor that can be set is a read-write
+monitor. It will catch any reference to or attempt to modify the
+`LVAL` of the *atom* specified. The restrictions on placement of
+breakpoints also apply to monitors, with the addition that a monitor
+on an `LVAL` must be placed after that `LVAL` has become `ASSIGNED?`.
+
+The second, third (and so on) arguments to `RW` are the same as those
+for `BK`. The *predicate* may be dependent on either the new or old
+value of the variable: These are available as the `LVAL`s of `NEWVAL`
+and `OLDVAL`, respectively.
+
+When a monitor is triggered, it prints the type of monitor, the
+variable being monitored, and any other information requested by the
+user, and then calls `LISTEN`.
+
+A monitor prints as yet another glyph:
+