@node Custom Output, Prompting, Format, Input/Output
@section Custom Output
-MIT/GNU Scheme provides hooks for specifying that certain kinds of objects
-have special written representations. There are no restrictions on the
-written representations, but only a few kinds of objects may have custom
-representation specified for them, specifically: records
-(@pxref{Records}), vectors that have special tags in their zero-th
-elements (@pxref{Vectors}), and pairs that have special tags in their
-car fields (@pxref{Lists}). There is a different procedure for
-specifying the written representation of each of these types.
-
-@deffn procedure set-record-type-unparser-method! record-type unparser-method
-Changes the unparser method of the type represented by @var{record-type}
-to be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a record of this type, it
-will invoke @var{unparser-method} to generate the written
-representation.
-@end deffn
-
-@deffn procedure unparser/set-tagged-vector-method! tag unparser-method
-Changes the unparser method of the vector type represented by @var{tag}
-to be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a vector with @var{tag} as
-its zero-th element, it will invoke @var{unparser-method} to generate
-the written representation.
-@end deffn
-
-@deffn procedure unparser/set-tagged-pair-method! tag unparser-method
-Changes the unparser method of the pair type represented by @var{tag} to
-be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a pair with @var{tag} in its
-car field, it will invoke @var{unparser-method} to generate the written
-representation.
-@end deffn
-
-@cindex unparser method (defn)
-@cindex method, unparser (defn)
-An @dfn{unparser method} is a procedure that is invoked with two
-arguments: an unparser state and an object. An unparser method
-generates a written representation for the object, writing it to the
-output port specified by the unparser state. The value yielded by an
-unparser method is ignored. Note that an unparser state is not an
-output port, rather it is an object that contains an output port as one
-of its components. Application programs generally do not construct or
-examine unparser state objects, but just pass them along.
-
-There are two ways to create an unparser method (which is then
-registered by one of the above procedures). The first, and easiest, is
-to use @code{standard-unparser-method}. The second is to define your
-own method using the procedure @code{with-current-unparser-state}. We
-encourage the use of the first method, as it results in a more uniform
-appearance for objects. Many predefined datatypes, for example
-procedures and environments, already have this appearance.
-
-@deffn procedure standard-unparser-method name procedure
-Returns a standard unparser method. @var{Name} may be any object, and
-is used as the name of the type with which the unparser method is
-associated; @var{name} is usually a symbol. @var{Procedure} must be
-@code{#f} or a procedure of two arguments.
+MIT/GNU Scheme provides hooks for specifying that specified objects
+have special written representations. There are no restrictions on
+the written representations.
+
+@deffn procedure define-print-method predicate print-method
+Defines the print method for objects satisfying @var{predicate} to be
+@var{print-method}. The @var{predicate} argument must be a unary
+procedure that returns true for the objects to print specially, and
+@var{print-method} must be a binary procedure that accepts one of
+those objects and a textual output port.
+
+Although @var{print-method} can print the object in any way, we
+strongly recomment using one of the following special printers.
+@end deffn
+
+@deffn procedure standard-print-method name [get-parts]
+The @var{name} argument may be a unary procedure, a string, or a
+symbol; if it is a procedure it is called with the object to be
+printed as its argument and should return a string or a symbol. The
+@var{get-parts} argument, if provided, must be a unary procedure that
+is called with the object to be printed and must return a list of
+objects. If @var{get-parts} is not provided, it defaults to a
+procedure that returns an empty list.
@cindex #[ as external representation
-If @var{procedure} is @code{#f}, the returned method generates an
-external representation of this form:
-
+The output generated by this method is in a standard format:
@example
-#[@var{name} @var{hash}]
+#[<name> <hash> <part>@dots{}]
@end example
-
-@noindent
-@findex write
-@findex write-string
-@findex hash
-Here @var{name} is the external representation of the argument
-@var{name}, as generated by @code{write},@footnote{Except that if the
-argument @var{name} is a string, its external representation is
-generated by @code{write-string}.} and @var{hash} is the external
-representation of an exact non-negative integer unique to the object
-being printed (specifically, it is the result of calling @code{hash} on
-the object). Subsequently, the expression
-
+where @code{<name>} is the string or symbol from @var{name} as printed by
+@code{display}, @code{<hash>} is a unique nonnegative integer generated
+by calling @code{hash-object} on the object, and the @code{<part>}s are
+the result of calling @var{get-parts} as printed by @code{write} and
+separated by spaces.
+
+One significant advantage of print methods generated by
+@code{standard-print-method} is that the parts returned by
+@var{get-parts} are examined when searching for circular structure (as
+by @code{write}) or shared structure (as by @code{write-shared}). In
+effect the printer sees one of these objects as a compound object
+containing those parts.
+@end deffn
+
+@deffn procedure bracketed-print-method name printer
+The @var{name} argument may be a unary procedure, a string, or a
+symbol; if it is a procedure it is called with the object to be
+printed as its argument and should return a string or a symbol. The
+@var{printer} argument must be a binary procedure, which is called
+with the object to print and a textual output port as its arguments.
+
+Similar to @code{standard-print-method}, this procedure prints an object
@example
-#@@@var{hash}
+#[<name> <hash><output>]
@end example
+where @code{<name>} is the string or symbol from @var{name} as printed by
+@code{display}, @code{<hash>} is a unique nonnegative integer generated
+by calling @code{hash-object} on the object, and @code{<output>} is the
+text written by @var{printer}.
-@noindent
-is notation for an expression evaluating to the object.
+This procedure has the benefit of printing objects using the standard
+bracketed form, but because its @var{output} is unstructured can not
+be examined for sharing or circularity. Generally speaking it's
+preferable to use @code{standard-print-method} instead.
+@end deffn
-If @var{procedure} is supplied, the returned method generates a slightly
-different external representation:
+The following are deprecated procedures that have been replaced by the
+above.
+@deffn {obsolete procedure} set-record-type-unparser-method! record-type unparser-method
+This procedure is @strong{deprecated}; instead use
@example
-#[@var{name} @var{hash} @var{output}]
+@group
+(define-print-method (record-constructor @var{record-type})
+ @var{unparser-method})
+@end group
@end example
+provided that @var{unparser-method} is really a print method.
+@end deffn
-@noindent
-Here @var{name} and @var{hash} are as above, and @var{output} is the
-output generated by @var{procedure}. The representation is constructed
-in three stages:
-
-@enumerate
-@item
-The first part of the format (up to @var{output}) is written to the
-output port specified by the unparser state. This is @code{"#["},
-@var{name}, @code{" "}, and @var{hash}.
-
-@item
-@var{Procedure} is invoked on two arguments: the object and an output
-port.
+@deffn {obsolete procedure} unparser/set-tagged-vector-method! tag unparser-method
+@deffnx {obsolete procedure} unparser/set-tagged-pair-method! tag unparser-method
+These procedures arg @strong{deprecated}. There is no direct replacement for them.
-@item
-The closing bracket is written to the output port.
-@end enumerate
+These were primarily used by @code{define-structure}, which now
+generates new-style print methods. If you have other uses of these,
+it should be possible to translate them to use
+@code{define-print-method} with hand-written predicates.
@end deffn
-The following procedure is useful for writing more general kinds of
-unparser methods.
-
-@deffn procedure with-current-unparser-state unparser-state procedure
-This procedure calls @var{procedure} with one argument, the output port
-from @var{unparser-state}. Additionally, it arranges for the remaining
-components of @var{unparser-state} to be given to the printer when they
-are needed. The @var{procedure} generates some output by writing to the
-output port using the usual output operations, and the value yielded by
-@var{procedure} is returned from @code{with-current-unparser-state}.
+@deffn {obsolete procedure} standard-unparser-method name procedure
+This procedure is @strong{deprecated}; it is currently an alias for
+@code{bracketed-print-method}.
+@end deffn
-The port passed to @var{procedure} should only be used within the
-dynamic extent of @var{procedure}.
+@deffn {obsolete procedure} with-current-unparser-state unparser-state procedure
+This procedure is @strong{deprecated}, with no direct replacement. In
+general just use @var{procedure} without wrapping it.
@end deffn
@node Prompting, Textual Port Primitives, Custom Output, Input/Output
The default behavior of this procedure is to print a fresh line, a
newline, and the prompt string; flush the output buffer; then read an
object and return it.
-
+v
Under Edwin and Emacs, before the object is read, the interaction buffer
is put into a mode that allows expressions to be edited and submitted
for input using specific editor commands. The first expression that is