
[NOTE: This file has been generated by a series of translation tools that
 converted an original FrameMaker .mif file to this .txt file.  The
 conversion tools created the table of contents and uppercases all
 identifiers.  The printed representation of all identifiers in this
 interface is lowercase, but it is not worth the effort to fix this .txt
 file to correct the uppercasing.]

                          GWYDION STREAMS FOR DYLAN
                          =========================

Designed by the Gwydion Project

Version 3.0:

------------------------------------------------------------------------------

Table of Contents
-----------------

1.  Overview

    1.1.  Classes

    1.2.  Functions

    1.3.  Buffers

    1.4.  Usage Models

    1.5.  Characters

    1.6.  Miscellaneous Features

2.  Classes and Other Types

3.  Constants

4.  The <stream> Protocol

    4.1.  Stream Extension Protocol

    4.2.  Basic I/O Protocol

    4.3.  Buffer Access Protocol

    4.4.  Data Extension Protocol

5.  The <random-access-stream> Protocol

6.  The <file-stream> Protocol

7.  The <string-input-stream> Protocol

8.   The <string-output-stream> Protocol

9.  The <buffer> Protocol

10.  Conditions

11.  Footnotes

------------------------------------------------------------------------------

This document describes the Streams library designed by the Gwydion Project
at Carnegie Mellon University. The primary goals of this stream interface
are efficiency, simplicity, and the ability to extend the stream protocol to
more complex stream objects and more complex data objects. The stream design
focuses on byte-oriented, buffered input and output. Implementations and
users have access to the internal buffers of streams for efficiency reasons.
Implementations and users can extend the stream protocol to a new stream
subclass just by extending the interface to the stream `s buffer.

The Streams library contains none of the following kinds of functionality:

  * complex stream subclasses implementing streams such as concatenated,
    broadcast, echo, two-way conglomerate, and so on.
  * formatted output, such as Common Lisp's FORMAT function or C's PRINTF.
  * formatted input, such as C's SCANF.
  * so called READable printing, such as Common Lisp's PRINT function.
  * parsing, such as Common Lisp's READ function.
  * output and input of arbitrary binary representations, such as dumping
    integers and floats in raw, implementation-dependent form.
  * streams that do not support the stream protocol entirely; for example, a
    record-oriented stream may not be able to support the READ-BYTE
    function.

Most of these items fit naturally on top of the Streams library, but
regardless of that, separate libraries should provide the kinds of
functionality listed above.

1.  Overview
------------
This section introduces some underlying concepts of the Streams library and
provides a sketch of the required stream classes and functions.

1.1.  Classes

The following classes are required (indentation shows subclass
relationship):

   <stream> [Abstract]
      <random-access-stream> [Abstract]
         <string-input-stream> [Abstract]
            <byte-string-input-stream> [Concrete]
         <string-output-stream> [Abstract]
            <byte-string-output-stream> [Concrete]
      <file-stream> [Abstract Instantiable]

Implementations are required to provide a concrete class that is a subclass
of <RANDOM-ACCESS-STREAM> and <FILE-STREAM>, and when users call the MAKE
function on <FILE-STREAM>, they get an instance o f this
implementation-dependent concrete class.

1.2.  Functions

This subsection sketches the functions exported from the Streams library.
This is not a complete list of applicable functions; for example, MAKE is
not listed for any class, and sequence operations are not listed for the
<BUFFER> class.

The following functions comprise the STREAM EXTENSION PROTOCOL (described in
Section THE <STREAM> PROTOCOL):

    CLOSE
    STREAM-EXTENSION-GET-INPUT-BUFFER
    STREAM-EXTENSION-RELEASE-INPUT-BUFFER
    FILL-INPUT-BUFFER
    INPUT-AVAILABLE-AT-SOURCE?
    STREAM-EXTENSION-GET-OUTPUT-BUFFER
    STREAM-EXTENSION-RELEASE-OUTPUT-BUFFER
    FORCE-OUTPUT-BUFFER
    SYNCHRONIZE-OUTPUT-BUFFER

The following functions comprise the BASIC I/O PROTOCOL (described in
Section THE <STREAM> PROTOCOL):

    READ-BYTE
    PEEK-BYTE
    READ-LINE
    INPUT-AVAILABLE?
    FLUSH-INPUT
    FORCE-OUTPUT
    SYNCHRONIZE-OUTPUT

The following functions comprise the BUFFER ACCESS PROTOCOL (described in
Section THE <STREAM> PROTOCOL):

    GET-INPUT-BUFFER
    RELEASE-INPUT-BUFFER
    GET-OUTPUT-BUFFER
    RELEASE-OUTPUT-BUFFER

The following functions comprise the DATA EXTENSION PROTOCOL (described in
Section THE <STREAM> PROTOCOL):

    READ-AS
    READ-INTO!
    WRITE
    WRITE-LINE

The following functions comprise the Random Access Protocol (described in
Section THE <RANDOM-ACCESS-STREAM> PROTOCOL):

    STREAM-POSITION
    STREAM-POSITION-SETTER
    ADJUST-STREAM-POSITION
    STREAM-SIZE

The following function comprises the <STRING-OUTPUT-STREAM> protocol
(described in Section THE <STRING-OUTPUT-STREAM> PROTOCOL):

    STRING-OUTPUT-STREAM-STRING

The following functions comprise the <BUFFER> protocol (described in Section
THE <BUFFER> PROTOCOL):

    BUFFER-SUBSEQUENCE
    COPY-FROM-BUFFER!
    COPY-INTO-BUFFER!

1.3.  Buffers

The Streams library provides the framework for defining various high-level
streams, such as Common Lisp has. As stated previously, one of the primary
goals of this stream interface is efficiency. The design of Common Lisp
streams is inherently inefficient. For example, in Common Lisp if you have a
general output routine for writing multiple items (or multiple components of
an object) to a stream, you pay a big penalty in having to perform generic
function invocation in the middle of your loop (or over a sequence of stream
operations). This is because you cannot know until run time what sort of
stream you have.

This stream interface solves this problem by providing a clean protocol for
directly manipulating the internal buffers of streams. Since all streams
have internal buffers that are instances of the same class, users can write
efficient, stream-independent output routines by operating on the streams'
buffers. Buffer methods can be fully determined at compile time. A Buffer is
an instance of the <BUFFER> class, which is a sealed subclass of <VECTOR>.
Buffers have element type <BYTE> (see Subsection MISCELLANEOUS DEFINITIONS
for type definitions).

When users manipulate buffers directly, they are entirely responsible for
maintaining the buffer's state. Once a user gets a stream's buffer, the
stream object has no means to track activity in the buffer. To use a
stream's buffer, users must explicitly get the buffer. At this time, the
stream indicates where the pending input or output is in the buffer. If the
stream is an input stream, users can consume as much of the pending input as
necessary, filling the buffer with input from the stream's source any number
of times, including none. If the stream is an output stream, users can store
as much pending output in the buffer as necessary, forcing out the output
any number of times, including none. When users are done with a stream's
buffer, they must explicitly release the buffer and indicate to the stream
the buffer's current state.

Stream implementations are required to be able to determine when an
application is explicitly using a stream's buffer. Between the time when an
application explicitly gets a stream's buffer and then later releases the
buffer, the application is said to HOLD the buffer. Many routines in the
stream interface are defined to only work correctly when the application
holds the stream's buffer. These routines are defined, with respect to
guaranteeing correct behavior and blocking behavior, to allow
implementations freedom to provide safe and good development environment
support and to provide good support for stream implementations in
multi-threaded execution environments. See Subsections STREAM EXTENSION
PROTOCOL and BUFFER ACCESS PROTOCOL.

When applications do not hold a stream's buffer, they cannot make any
assumptions about the maintenance of the buffer. In particular, it is an
error to save references to buffers, perform operations on buffers when not
holding them (such as ELEMENT-SETTER), and so on.

1.4.  Usage Models

The Streams library supports three styles of usage. The first, and probably
most common, is a simple style that uses high-level input and output
functions, such as READ-BYTE, READ-AS, WRITE, and so on. The simple style
will be the least efficient, but it provides convenience and is generally
useful. In the second style, applications use the internal buffers of
streams to grab multiple bytes of input at once or to provide multiple bytes
of output at once. Using the buffers is relatively efficient, less
convenient for the programmer, but generally just as useful as the simple
style. In the third style, applications directly allocate buffers and use
them for reading and writing very large chunks of data, probably whole files
at once. Directly using buffers separately from the internal buffers of
streams provides the greatest efficiency and is slightly less complicated
than the second style of usage; however, the third style has very specific
uses and does not mix well with the first style.

The second style of usage is quite flexible. Users can mix the first and
second styles of usage. Though users must explicitly get and release buffers
to use buffers directly, when the buffers are not held, simple style input
and output integrates smoothly with input read from and output placed in
buffers directly. The second style of usage also provides more precise
control over blocking behavior for some operations that are logically
equivalent in the two styles.

Implementations should support the third style of usage without any
unnecessary inefficiencies, such as double buffering. The Streams library
provides functions such as READ-INTO! and WRITE that should have method that
allow users to very efficiently fill a large buffer from a stream's source
or deliver a large buffer to a stream's destination.

1.5.  Characters

Because international character standards and file formats are still
converging on a clear winner, this stream interface specifies very little
about characters. Implementors are required to provide a subclass of
<CHARACTER> called <BYTECHARACTER> and methods specialized on this class for
the READ-AS and WRITE generic functions. The <BYTE-CHARACTER> class
represents the ASCII character set (or extensions to ASCII). The Streams
library requires support for ASCII characters because they capture a large
portion of character I/O, and their use should be standard. Implementations
are free to support other characters, and their support can naturally fit
into the Streams library.

1.6.  Miscellaneous Features

The Streams library provides streams that support input operations, streams
that support output operations, and streams that support both. The kind of
operations supported by a particular stream is determined by keywords
supplied when making the stream (such as with <FILE-STREAM> instances) or by
the class of the stream (such as with <STRING-INPUT-STREAM>).
Implementations of output streams should arrange to have the Dylan run-time
system force output when an application exits, but portable programs do not
rely on this feature.

When OPENING is applicable, users open a stream by calling MAKE on a stream
class. The initialization protocols for the different subclasses of <STREAM>
take keyword arguments that are appropriate to each subclass. The MAKE
function returns an open stream object. Unless otherwise specified, it is an
error to use stream operations on closed streams.

When describing the stream protocol relating to buffers, this document uses
the term END to discuss the end of valid data in buffers. The use of END is
always an exclusive end of the data, that is, the buffer's element indicated
by an end value is never part of the valid data. An end value may not be a
valid buffer index; because Dylan sequences have zero-based indexes, an end
value may be equal to the size of the buffer.

This document declares some arguments and return values to have the type
<BOOLEAN>. This is not part of Dylan, and the Streams library does not
export it. As used in this document, it has the following definition:

   union(singleton(#t), singleton(#f))

This document declares some arguments and return values to have the type
<FIXED-INTEGER> to designate an implementation-dependent, finite integer
type. The intent is that these integers are known to be small, lightweight
integers (and will never be infinite precision integers).

2.  Classes and Other Types
---------------------------
The Streams library exports the following classes:

<STREAM>  [Abstract Class]

        This class is a subclass of <OBJECT>. All streams inherit from this
        class. MAKE of <STREAM> subclasses accepts a size: keyword argument
        that indicates the user's choice for a buffer size. Users must check
        the size of the stream's buffer because implementations may ignore
        the size: argument.

<RANDOM-ACCESS-STREAM>  [Abstract Class]

        This class is a subclass of <STREAM>. All required streams in the
        Streams library inherit from this class, which means they support
        the Random Access Protocol. Some implementations may provide streams
        that do not inherit from this class (for example, a UnixTM socket
        stream).

<FILE-STREAM>  [Abstract Instantiable Class]

        This class is a subclass of <STREAM>. When users instantiate this
        class, they get an implementation-dependent indirect instance that
        is both a <FILE-STREAM> and a <RANDOM-ACCESS-STREAM>. See Section
        THE <FILE-STREAM> PROTOCOL for the details of making these streams.

<STRING-INPUT-STREAM>  [Abstract Class]

        This class is a subclass of <RANDOM-ACCESS-STREAM>. MAKE of
        <STRING-INPUT-STREAM> subclasses requires a string: keyword argument
        that is an instance of <string>, and input operations on these
        streams read from the supplied string.

<BYE-STRING-INPUT-STREAM>  [Concrete Class]

        This class is a subclass of <STRING-INPUT-STREAM>. The string:
        argument to MAKE must be a <BYTE-STRING>.

<STRING-OUTPUT-STREAM>  [Abstract Class]

        This class is a subclass of <RANDOM-ACCESS-STREAM>. These streams
        collect their output, and when requested, they return the output as
        a <BYTE-STRING>.

<BYTE-STRING-OUTPUT-STREAM>  [Concrete Class]

        This class is a subclass of <STRING-OUTPUT-STREAM>.

<BYTE-CHARACTER>  [Type]

        This type is a subtype of <CHARACTER>. Characters of this type
        represents the ASCII character set (or extensions to ASCII).

<BUFFER>  [Concrete Class]

        This class is a sealed subclass of <VECTOR>. These are the buffers
        used by every general instance of <STREAM>. The element type of
        buffers is <BYTE>.
        The <BUFFER> class appears to the user to be semantically the same
        as the <BYTE-VECTOR> class, but implementors of the Streams library
        may make use of internal systems storage or other internal features.
        For example, an implementation might make buffers more suitable for
        directly passing them to system calls or for maintaining interior
        pointers into buffers, but users will be unaware o f any such
        implementation tactics.

<BUFFER-INDEX>  [Type]

        This is the type of values used to index buffers.

<BYTE>  [Type]

        This type represents limited integers: limited(<integer>, min: 0,
        max: 255).

<BYTE-VECTOR>  [Concrete Class]

        This class is a sealed subclass of <VECTOR>. The element type of
        byte-vectors is <BYTE>.

3.  Constants
-------------
The Streams library exports the following constants:

$MAXIMUM-BUFFER-SIZE  [Constant]

        This constant holds the maximum SIZE: argument that users can supply
        when making buffers and streams.

4.  The <stream> Protocol
-------------------------
The <STREAM> protocol categorizes operations into three groups:

    Stream Extension Protocol
        Generic functions that anyone can use to extend the stream protocol
        to new subclasses of streams. Implementations are required to have
        sealed methods for this group's functions on the standard stream
        subclasses.
    Basic I/O Protocol
        Functions implemented on top of the Stream Extension Protocol. Users
        should not need to add methods to the Basic I/O Protocol functions
        when they define new stream subclasses.
    Buffer Access Protocol
        Functions implemented on top of the Stream Extension Protocol. These
        provide the means for users to get and release streams' buffers.
        Users should never define new methods for these functions.
    Data Extension Protocol
        Generic functions that are specialized to return or accept various
        classes of objects when reading or writing. Implementations are
        required to provide sealed methods for a few classes of data
        objects. Implementations are free to forgo methods for many classes
        of objects, and there may not even be a default method for <OBJECT>.
        The Data Extension Protocol typically specializes methods based on
        the classes of data objects returned by reading or accepted for
        writing. Sometimes these functions need to specialize on the stream
        as well as the data; for example, to most efficiently deliver a
        buffer to an output stream's destination, a method may need to be
        specific to a stream.

4.1.  Stream Extension Protocol

This subsection of the <STREAM> protocol describes the Stream Extension
Protocol. These are the functions that users extend when defining new stream
subclasses:

    CLOSE
    STREAM-EXTENSION-GET-INPUT-BUFFER
    STREAM-EXTENSION-RELEASE-INPUT-BUFFER
    FILL-INPUT-BUFFER
    INPUT-AVAILABLE-AT-SOURCE?
    STREAM-EXTENSION-GET-OUTPUT-BUFFER
    STREAM-EXTENSION-RELEASE-OUTPUT-BUFFER
    FORCE-OUTPUT-BUFFER
    SYNCHRONIZE-OUTPUT-BUFFER

The make method for all stream classes takes a SIZE: keyword argument that
suggests the buffer size that the user thinks will be best for the stream's
use. Users must still inspect the size returned when fetching the buffer
because they may not get the size requested.

CLOSE  [Generic Function]

    Arguments
        stream :: <stream>
    Values
        meaningless :: singleton(#f)
    Description
        Closes STREAM and potentially frees any resources backing it. If
        STREAM supports output, then this function forces any pending
        output. It is an error to call the CLOSE function on a stream while
        its buffer is held. This function returns #f as a meaningless return
        value.

STREAM-EXTENSION-GET-INPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
    Values
        buffer :: <buffer>
        next :: <buffer-index>
        end :: <buffer-index>
    Description
        Returns the input buffer for STREAM. Users of a stream object never
        call this function; it exists only for users to extend the stream
        protocol to new stream subclasses. See the definition of
        GET-INPUT-BUFFER.

        This function also returns the stream's state relative to the
        buffer, which is the next available byte for input and the end of
        available bytes for input. The following diagram illustrates the
        additional return values:

                         +-----------------------------+
                buffer:  | | | | | | | | | | | | | | | |
                         +-----------------------------+
                                    ^           ^
                                 next         end

        Consider a buffer that has input in it from the stream's source.  At
        any point the following is true:

          * The bytes contained between locations zero, inclusively, and
            NEXT, exclusively, have already been consumed by some user of
            the stream.
          * The bytes contained between locations NEXT, inclusively, and
            END, exclusively, have not been consumed by any user of the
            stream.
          * The bytes contained between locations END, inclusively, and the
            size of the buffer, exclusively, are undefined.

        This function may return a buffer with no available input; this is
        true when NEXT == END.1

        If STREAM is an output only stream, then this signals an error. If
        the application already holds the buffer, then this function signals
        an error.

STREAM-EXTENSION-RELEASE-INPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
        next :: <buffer-index>
        end :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Announces that the user is done with STREAM's buffer and updates
        STREAM's state relative to the buffer.  Users of a stream object
        never call this function; it exists only for users to extend the
        stream protocol to new stream subclasses.  See the definition of
        RELEASE-INPUT-BUFFER.

        Because STREAM has no way to keep track of its buffer's state while
        users manipulate the buffer directly, users must pass information
        back to STREAM to indicate where pending input, if any, is in the
        buffer. The NEXT argument indicates the location of the first byte,
        if any, remaining to be read. The END argument indicates the end of
        any pending input in the buffer. See
        STREAM-EXTENSION-GET-INPUT-BUFFER for details on these values.

        This function returns #f as a meaningless return value.

FILL-INPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
        start :: <buffer-index>
    Values
        end :: <buffer-index>
    Description
        Gets as much input as is available and that will fit in STREAM's
        buffer from the START location to the buffer size.  Because STREAM
        has no way to keep track of its buffer's state while users
        manipulate the buffer directly, users must indicate where pending
        input, if any, is in the buffer. The START argument serves this
        purpose and provides users the flexibility to get more input while
        leaving some pending input in the buffer.

        This function returns the end of the newly available input.  If no
        input is available, this function blocks until some input is
        available; however, when this function detects the end of the
        stream's source, it returns zero instead of blocking.

        If the application does not hold STREAM's buffer, this function
        signals an error.

INPUT-AVAILABLE-AT-SOURCE?  [Generic Function]

    Arguments
        stream :: <stream>
    Values
        input-available? :: <boolean>
    Description
        Returns #t when STREAM's source has any available input or when the
        stream is at the end of its source.  If this function returns #t,
        then the next call to FILL-INPUT-BUFFER will not block.  It is an
        error to call this function without holding the buffer.

STREAM-EXTENSION-GET-OUTPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
    Values
        buffer :: <buffer>
        next :: <buffer-index>
        end :: <buffer-index>
    Description
        Returns the output buffer for STREAM. Users of a stream object never
        call this function; it exists only for users to extend the stream
        protocol to new stream subclasses.  See the definition of
        GET-OUTPUT-BUFFER.

        This function also returns STREAM's state relative to the buffer,
        which is the next location available to place output and the size of
        the buffer (the end of available locations for placing output).  The
        following diagram illustrates the additional return values:

                         +-----------------------------+
                buffer:  | | | | | | | | | | | | | | | |
                         +-----------------------------+
                                  ^                     ^
                               next                   end

        Consider a buffer that has pending output in it.  At any point the
        following is true:

          * The bytes contained between locations zero, inclusively, and
            NEXT, exclusively, are pending output and need to be forced out
            to the stream's destination.
          * The bytes contained between locations NEXT, inclusively, and
            END, exclusively, are undefined.

        This function never returns a full output buffer.

        If STREAM is an input only stream, then this signals an error.  If
        the application already holds the buffer, then this function signals
        an error.

STREAM-EXTENSION-RELEASE-OUTPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
        next :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Announces that the user is done with STREAM's buffer and updates
        STREAM's state relative to the buffer.  Users of a stream object
        never call this function; it exists only for users to extend the
        stream protocol to new stream subclasses.  See the definition of
        RELEASE-OUTPUT-BUFFER.

        Because STREAM has no way to keep track of its buffer's state while
        users manipulate the buffer directly, users must pass information
        back to STREAM to indicate where pending output, if any, is in the
        buffer. The NEXT argument indicates the end of the pending output,
        if any. See STREAM-EXTENSION-GET-OUTPUT-BUFFER for details on these
        values.

        This function returns #f as a meaningless return value.

FORCE-OUTPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
        end :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Forces out the contents of STREAM's buffer from location zero to
        END.  Because STREAM has no way to keep track of its buffer's state
        while users manipulate the buffer directly, users must indicate
        where the pending output is in the buffer. When this function
        returns, the user may begin placing more output in the buffer.

        If the application does not hold the buffer, this function signals
        an error.

        This function returns #f as a meaningless return value.

SYNCHRONIZE-OUTPUT-BUFFER  [Generic Function]

    Arguments
        stream :: <stream>
        end :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Forces out the contents of STREAM's buffer from location zero to
        END.  This returns only when the buffer may be used further by the
        application. This function also does whatever it can to ensure the
        output reaches the stream's destination before returning, thereby
        synchronizing the output destination with the application.  For
        example, if STREAM delivered its output to an editor,
        FORCE-OUTPUT-BUFFER would only be required to inject the output into
        the editor's text representation, but SYNCHRONIZE-OUTPUT-BUFFER
        might call the editor's redisplay function.  As another example,
        consider a FORCE-OUTPUT-BUFFER implementation that copied the
        contents of a stream's buffer and queued the copy for output to the
        stream's destination, possibly because delivering that output is
        especially slow or may incur network overhead; the implementation of
        SYNCHRONIZE-OUTPUT-BUFFER for that stream should wait until the
        queue of output becomes empty and possibly even perform an extra
        handshake with the destination to ensure the output was received.

        If the application does not hold the buffer, this function signals
        an error.

        This function returns #f as a meaningless return value.

4.2.  Basic I/O Protocol

This subsection of the <STREAM> protocol describes the Basic I/O Protocol.
Users should not need to add methods to the Basic I/O Protocol functions
when they define new stream subclasses. The reading and writing functions
primarily only operate on bytes. This subsection describes the following
functions:

    READ-BYTE
    PEEK-BYTE
    READ-LINE
    INPUT-AVAILABLE?
    FLUSH-INPUT
    FORCE-OUTPUT
    SYNCHRONIZE-OUTPUT

READ-BYTE  [Function]

    Arguments
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        union(<byte>, singleton(#f))
    Description
        Returns one byte from STREAM. This function blocks until input is
        available.  If reading from stream encounters the end of the stream,
        then the SIGNAL-EOF? argument determines the behavior of this
        function. If SIGNAL-EOF? is #t (the default), then this function
        signals an <END-OF-FILE> condition (see Section CONDITIONS);
        otherwise, this function returns #f.

PEEK-BYTE   [Function]

    Arguments
        stream :: <stream>
    values
        byte :: union(<byte>, singleton(#f))
    Description
        Returns the next byte in the input without advancing the STREAM's
        position. This function blocks until input is available. If reading
        from STREAM encounters the end of the stream, then this function
        returns #f.

READ-LINE  [Function]

    Arguments
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        line :: union(<string>, singleton(#f))
        eof? :: <boolean>
    Description
        Returns as a <BYTE-STRING> all the input to the next newline
        character.1 The resulting string excludes the newline character.
        This routine blocks until it encounters a newline or the end of the
        stream's source.  As a second value, this function returns a boolean
        to indicate whether the line terminated with the end of the stream's
        source (#t) or a newline (#f).

        Whenever a call to READ-LINE encounters the end of STREAM's source
        immediately (that is, there is no input to read), then the
        SIGNAL-EOF? argument determines the behavior of this function. In
        this situation, if SIGNAL-EOF? is #t (the default), then this
        function signals an <END-OF-FILE> error; otherwise, it returns #f
        and #t as multiple values.

INPUT-AVAILABLE?  [Function]

    Arguments
        stream :: <stream>
    Values
        input-available? :: <boolean>
    Description
        Returns #t when STREAM has available input or when the stream is at
        the end of its source.  If this function returns #t, then the next
        call to READ-BYTE will not block.  Note, though the next call to
        READ-BYTE will not block, READ-BYTE will signal an <END-OF-FILE>
        condition (or return #f) if the stream is at the end of its source.

FLUSH-INPUT  [Function]

    Arguments
        stream :: <stream>
    Values
        meaningless :: singleton(#f)
    Description
        Flushes all pending input from STREAM, both buffered input and, if
        possible, any that is available at STREAM's source. This function
        returns #f as a meaningless return value.

FORCE-OUTPUT  [Function]

    Arguments
        stream :: <stream>
    Values
        meaningless :: singleton(#f)
    Description
        Forces any pending output from STREAM's buffer to STREAM's
        destination.  This function corresponds to FORCEOUTPUT-BUFFER but
        provides a higher-level interface for the more common situation
        where the user does not hold the stream's output buffer. This
        function returns #f as a meaningless return value.

SYNCHRONIZE-OUTPUT  [Function]

    Arguments
        stream :: <stream>
    Values
        meaningless :: singleton(#f)
    Description
        Forces any pending output from STREAM's buffer to STREAM's
        destination.  This function also does whatever it can to ensure the
        output reaches the stream's destination before returning, thereby
        synchronizing the output destination with the application.  This
        function corresponds to SYNCHRONIZE-OUTPUT-BUFFER, providing a
        higher-level interface for the more common situation where the user
        does not hold the stream's output buffer.  See the definition of
        SYNCHRONIZE-OUTPUT-BUFFER for more information. This function
        returns #f as a meaningless return value.

4.3.  Buffer Access Protocol

This subsection of the <STREAM> protocol describes the Buffer Access
Protocol. These functions provide users the means to get and release input
and output buffers. Users should never add methods to these functions. This
subsection describes the following functions:

    GET-INPUT-BUFFER
    RELEASE-INPUT-BUFFER
    GET-OUTPUT-BUFFER
    RELEASE-OUTPUT-BUFFER

These functions call their corresponding functions from the Stream Extension
Protocol. For example, GETINPUT-BUFFER calls
STREAM-EXTENSION-GET-INPUT-BUFFER. Users always call the Buffer Access
Protocol functions to get and release buffers, never the STREAM-EXTENSION-
functions. Threaded Dylan implementations should place system-dependent
mutual exclusion calls in the Buffer Access Protocol functions. The
existence of these functions allows users to more portably extend the stream
protocol to new streams.  Users avoid the following design and maintenance
hassles:

  * Deciding whether to write for a threaded or a non-threaded Dylan
    implementation.
  * Rewriting mutual exclusion code for each Dylan implementation.
  * Having to duplicate mutual exclusion code wherever the application uses
    stream buffers directly.

GET-INPUT-BUFFER  [Function]

    Arguments
        stream :: <stream>
    values
        buffer :: <buffer>
        next :: <buffer-index>
        end :: <buffer-index>
    Description
        Returns the input buffer for STREAM. See the definition of
        STREAM-EXTENSION-GET-INPUT-BUFFER for details on the return values
        and behavior of this function.

        If an application calls this function, and the application already
        holds the input or output buffer for stream, then this function
        might block.  Multi-threaded implementations should eventually
        return.  All implementations are free to provide some form of
        recovery for environmental reasons; for example, if the environment
        is single-threaded, and users can cause the main stream of I/O to
        block due to re-entrancy or whatever, then implementations are free
        to detect this and take action to keep the environment accessible to
        the users.

RELEASE-INPUT-BUFFER  [Function]

    Arguments
        stream :: <stream>
        next :: <buffer-index>
        end :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Announces that the user is done with STREAM's buffer and updates
        STREAM's state relative to the buffer. See the definition of
        STREAM-EXTENSION-GET-INPUT-BUFFER for details on the arguments. If
        the application does not hold the buffer, this function signals an
        error. This function returns #f as a meaningless return value.

GET-OUTPUT-BUFFER  [Function]

    Arguments
        stream :: <stream>
    Values
        buffer :: <buffer>
        next :: <buffer-index>
        size :: <buffer-index>
    Description
        Returns the output buffer for STREAM. See the definition of
        STREAM-EXTENSION-GET-OUTPUT-BUFFER for details on the return values
        and behavior of this function.

        If an application calls this function, and the application already
        holds the input or output buffer for stream, then this function
        might block.  Multi-threaded implementations should eventually
        return.  All implementations are free to provide some form of
        recovery for environmental reasons; for example, if the environment
        is single-threaded, and users can cause the main stream of I/O to
        block due to re-entrancy or whatever, then implementations are free
        to detect this and take action to keep the environment accessible to
        the users.

RELEASE-OUTPUT-BUFFER  [Function]

    Arguments
        stream :: <stream>
        next :: <buffer-index>
    Values
        meaningless :: singleton(#f)
    Description
        Announces that the user is done with STREAM's buffer and updates
        STREAM's state relative to the buffer.  See the definition of
        STREAM-EXTENSION-GET-INPUT-BUFFER for details on the arguments. If
        the application does not hold the buffer, this function signals an
        error. This function returns #f as a meaningless return value.

4.4.  Data Extension Protocol

This subsection of the <STREAM> protocol describes the Data Extension
Protocol.  These functions provide higher-level reading and writing
operations, and they allow users to extend reading and writing to new
classes of data objects.  The Data Extension Protocol typically specializes
methods based on the classes of data objects returned by reading or accepted
for writing. Sometimes these functions need to specialize on the stream as
well as the data; for example, to most efficiently deliver a buffer to an
output stream's destination, a method may need to be specific to a stream.
This subsection describes the following functions:

    READ-AS
    READ-INTO!
    WRITE
    WRITE-LINE

READ-AS  [Generic Function]

    Arguments
        result-class :: <class>
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        union(<object>, singleton(#f))
        eof? :: <object>
    Description
        Reads and returns an instance of RESULT-CLASS from STREAM. The
        second return value indicates whether reading from STREAM
        encountered the end of the stream's source. Methods of READ-AS may
        take appropriate keywords to specify the constraints of the read.
        This function blocks until it can complete the read specified.

        If reading from STREAM encounters the end of the stream, then the
        SIGNAL-EOF? argument determines the behavior of this function. If
        SIGNAL-EOF? is #t (the default), then this function signals an
        <END-OF-FILE> error (see Section CONDITIONS); otherwise, it returns
        #f and #t as multiple values.

        The READ-AS function differs from READ-INTO! in that READ-AS makes
        the object returned.

READ-AS  [Sealed Method]

    Arguments
        result-class :: <byte>
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        union(<byte>, singleton(#f))
        eof? :: <boolean>
    Description
        Returns a byte from STREAM according to the description of the
        READ-AS generic function.

READ-AS  [Sealed Method]

    Arguments
        result-class :: <byte-character>
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        union(<byte-character>, singleton(#f))
        eof? :: <boolean>
    Description
        Returns a byte-character from STREAM according to the description of
        the READ-AS generic function.

READ-AS  [Method]

    Arguments
        result-class :: one-of(<byte-string>, <byte-vector>, <buffer>)3
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
        count :: <fixed-integer>
        to-eof? :: <boolean> = #f
    Values
        result :: type-or(<byte-string>, <byte-vector>, <buffer>,
        singleton(#f))4
        eof?-or-how-much :: union(<boolean>, <fixed-integer>)
    Description
        Reads and returns an instance of RESULT-CLASS from STREAM according
        to the description of the READ-AS generic function, with the noted
        exceptions below. Implementations are required to provide sealed
        methods for the RESULT-CLASS values.

        Supplying a COUNT: argument specifies a required read. The argument
        is the required size of the RESULT. If this method cannot satisfy
        the read request, then it regards SIGNAL-EOF? according to the
        description of the READ-AS generic function.

        Supplying the TO-EOF? argument as #t indicates the user wants to
        read all the data available up to the end of the stream's source.
        Supplying the TO-EOF? argument as #t effectively overrides the
        SIGNAL-EOF? argument. In this situation, this method always returns
        an object of the requested type, and the second return value is
        always the number of bytes read. The TO-EOF? behavior exists as a
        convenience to support a style of reading on streams that do not
        adhere to the Random Access Protocol; streams that do adhere to the
        Random Access Protocol allow users to compute how much data remains
        to be read.

        This function returns buffers to support users who need to perform
        very big reads as efficiently as possible. Implementations should
        support returning buffers as directly as possible, avoiding double
        buffering or other unnecessary inefficiencies. Of course, any
        pending input in the stream's buffer must be placed in the result
        buffer as part of completing the read specified.

READ-INTO!  [Generic Function]

    Arguments
        destination :: <object>
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
    Values
        destination :: union(<object>, singleton(#f))
        eof? :: <object>
    Description
        Fills in DESTINATION with input from STREAM. The second return value
        indicates whether reading from stream encountered the end of the
        stream's source. Methods of READ-INTO! may take appropriate keywords
        to specify the constraints of the read. This function blocks until
        it can complete the read specified.

        If reading from STREAM encounters the end of the stream, then the
        SIGNAL-EOF? argument determines the behavior of this function. If
        SIGNAL-EOF? is #t (the default), then this function signals an
        <END-OF-FILE> error (see Section CONDITIONS); otherwise, it returns
        #f and #t as multiple values.

READ-INTO!  [Method]

    Arguments
        destination :: type-or(<byte-string>, <byte-vector>, <buffer>)4
        stream :: <stream>
        #key signal-eof? :: <boolean> = #t
        start :: <fixed-integer> = 0
        end :: <fixed-integer> = destination.size
        to-eof? :: <boolean> = #f
    Values
        destination :: type-or(<byte-string>, <byte-vector>, <buffer>,
        singleton(#f))
        eof?-or-end :: union(<boolean>, <fixed-integer>)
    Description
        Fills in DESTINATION with input from STREAM according to the
        description of the READ-INTO! generic function, with the noted
        exceptions below. Implementations are required to provide sealed
        methods for the DESTINATION classes.

        When TO-EOF? is #f, the invocation specifies a required read. If
        this method cannot satisfy the read request designated by START and
        END,, then it regards SIGNAL-EOF? according to the description of
        the READ-INTO! generic function.

        Supplying the TO-EOF? argument as #t indicates the user wants to
        read all the data available up to the end of the stream's source.
        Supplying the TO-EOF? argument as #t effectively overrides the
        SIGNAL-EOF? argument and the END argument. In this situation, this
        method always returns DESTINATION, and the second return value is
        always the end of the data read into DESTINATION. If the stream has
        more than (destination.size - start) number of bytes available, then
        this method signals an error. The TO-EOF? behavior exists as a
        convenience to support a style of reading on streams that do not
        adhere to the Random Access Protocol; streams that do adhere to the
        Random Access Protocol allow users to compute how much data remains
        to be read.

        This function takes a buffer to support users who need to perform
        very big reads as efficiently as possible. Implementations should
        support filling the argument buffer as directly as possible,
        avoiding double buffering or other unnecessary inefficiencies. Of
        course, any pending input in the stream's buffer must be placed in
        the argument buffer as part of completing the read specified.

WRITE  [Generic Function]

    Arguments
        stream :: <stream>
        object :: <object>
        #key
    Values
        stream :: <stream>
    Description
        Writes OBJECT to STREAM. Methods of WRITE may take appropriate
        keywords to specify the constraints of the write.

        Note, because a sealed method for <BYTE> is required, users should
        not extend this protocol to <INTEGER>.  Another library will provide
        more general and higher-level output functionality, such as printing
        <INTEGER> instances in a human readable format or printing strings
        in a Dylan parse-able format.

WRITE  [Sealed Method]

    Arguments
        stream :: <stream>
        byte :: <byte>
    Values
        stream :: <stream>
    Description
        Writes BYTE to STREAM.

WRITE  [Sealed Method]

    Arguments
        stream :: <stream>
        char :: <byte-character>
    Values
        stream :: <stream>
    Description
        Writes CHAR to STREAM.

WRITE  [Method]

    Arguments
        stream :: <stream>
        object :: type-or(<byte-vector>, <byte-string>, <buffer>)4
        #key start :: <fixed-integer> = 0
        end :: <fixed-integer> = object.size
    Values
        stream :: <stream>
    Description
        Writes OBJECT to STREAM. Implementations are required to provide
        sealed methods for the specified classes of OBJECT:.
        This function takes a buffer to support users who need to perform
        very big writes as efficiently as possible. Implementations should
        deliver the contents of the argument buffer as directly as possible
        to the stream's destination, avoiding double buffering or other
        unnecessary inefficiencies. Of course, any pending output in the
        stream's buffer must be delivered to the stream's destination ahead
        of the argument buffer.

WRITE-LINE  [Generic Function]

    Arguments
        stream :: <stream>
        object :: <object>
        #key
    Values
        <stream>
    Description
        Writes OBJECT to stream with the WRITE function, and then writes a
        newline character.  All keyword arguments are passed to the WRITE
        function.  Multi-threaded implementations should arrange for the
        output of the WRITE call on OBJECT and the newline to be contiguous.

5.  The <random-access-stream> Protocol
---------------------------------------
This section describes the following functions from the Streams library:

    STREAM-POSITION
    STREAM-POSITION-SETTER
    ADJUST-STREAM-POSITION
    STREAM-SIZE

Setting or adjusting an output stream's position to be at a location before
the end of the stream does not truncate the stream. The stream must support
overwriting of previous output.

STREAM-POSITION  [Generic Function]

    Arguments
        stream :: <random-access-stream>
    Values
        position :: <integer>
    Description
        Returns STREAM's position for reading or writing as the offset from
        position zero. If the stream's buffer is held, then this function
        signals an error.

STREAM-POSITION-SETTER  [Generic Function]

    Arguments
        position :: <integer>
        stream :: <random-access-stream>
    Values
        position :: <integer>
    Description
        Sets STREAM's position for reading or writing to be POSITION.. If
        POSITION is less than zero or greater than streamsize(stream), this
        function signals an error. If the stream's buffer is held, then this
        function signals an error.

ADJUST-STREAM-POSITION  [Generic Function]

    Arguments
        offset :: <integer>
        stream :: <random-access-stream>
        #key from :: one-of(#"start", #"current", #"end")3 = #"start"
    Values
        position :: <integer>
    Description
        Sets STREAM's position for reading or writing to be OFFSET from the
        FROM argument. This function returns the new absolute position in
        the stream. If the new absolute position is less than zero, then
        this function signals an error. If the new absolute position is
        greater than streamsize(stream), then this function extends the
        stream's size to equal the new position, and the bytes from the old
        size to the new size are filled with zeroes. If the stream's buffer
        is held, then this function signals an error.

STREAM-SIZE  [Generic Function]

    Arguments
        stream :: <random-access-stream>
    Values
        <integer>
    Description
        Returns the number of bytes in STREAM . For input streams, this is
        the number of bytes that were available when the stream was made.
        For output streams, this is the number of bytes that would be
        present at the stream's destination if the application were to
        synchronize output and close the stream. If the stream's buffer is
        held, then this function signals an error.

6.  The <file-stream> Protocol
------------------------------
The Streams library does not provide a general file system interface,
offering such operations as probing files, deleting files, renaming files,
querying file authors and write dates, and so on.  These kinds of operations
should be provided by a separate library.

When users instantiate the <FILE-STREAM> class, they get an
implementation-dependent indirect instance that is both a <FILESTREAM> and a
<RANDOM-ACCESS-STREAM>. The MAKE method for <FILE-STREAM> and its subclasses
takes the following keywords:

    NAME:
        This parameter specifies the filename to open.  It must be a
        <STRING>.
    DIRECTION:
        This parameter specifies whether the stream will support input,
        output, or both operations.  It takes the following values:

        #"input"
            Results in an input stream.  This is the default.  If the file
            does not exist, then the make method signals a <FILE-NOT-FOUND>
            error.
        #"output"
            Results in an output stream.
        #"input-output"
            Results in a stream that supports input an output operations.

    IF-EXISTS:
        This parameter specifies what action to take when DIRECTION: is
        #"output" or #"input-output", and the indicated file already exists.
        It takes the following values:

        #"signal"
            Signals a <FILE-EXISTS> error.
        #"replace" (the default)
            Replaces the existing file with new output.
        #"overwrite"
            Opens the file such that output operations destructively modify
            the exiting file.  When specifying DIRECTION: as
            #"input-output", it is important to distinguish whether the
            system should truncate the file size to zero.  Specifying
            IF-EXISTS: as #"overwrite" preserves the existing contents of
            the file as opposed to #"replace". The file position will be at
            the start of the file.
        #"append"
            Opens the file such that output operations destructively modify
            the exiting file.  This is the same as #"overwrite", except that
            the file position will be at the end of the file.

7.  The <string-input-stream> Protocol
--------------------------------------
The make method for <STRING-INPUT-STREAM> takes a required STRING: keyword
argument. The make method also takes START: and END: keywords for the
string.  Reading starts at START:, and the stream signals <END-OF-FILE> when
the user attempts to read past the exclusive END:.

8.   The <string-output-stream> Protocol
----------------------------------------
The <STRING-OUTPUT-STREAM> class supports the following operation from the
Streams library:

STRING-OUTPUT-STREAM-STRING  [Generic Function]

    Arguments
        stream :: <string-output-stream>
    Values
        output :: <string>
    Description
        Returns all the output accumulated in STREAM since the last call to
        STRING-OUTPUT-STREAM-STRING.  If this function was never called on
        STREAM since the stream's creation, then this function returns all
        the output accumulated since the stream's creation. Implementations
        are required to provide a sealed method for <BYTESTRINGOUTPUTSTREAM>
        that returns a <BYTE-STRING>. If the stream's buffer is held, then
        this function signals an error.

9.  The <buffer> Protocol
-------------------------
The <BUFFER> class is a sealed subclass of <VECTOR>.  This section describes
the following generic functions from the Streams library:5

    BUFFER-SUBSEQUENCE
    COPY-FROM-BUFFER!
    COPY-INTO-BUFFER!

Implementations should provide very fast (machine-level) byte copying for
the required methods for these functions.

BUFFER-SUBSEQUENCE  [Generic Function]

    Arguments
        buffer :: <buffer>
        result-class :: <class>
        start :: <buffer-index>
        end :: <buffer-index>
    Values
        result :: <sequence>
    Description
        Returns an instance of RESULT-CLASS using the elements from BUFFER
        between START, inclusively, and END, exclusively.  Implementations
        are required to provide sealed methods for the following
        RESULT-CLASS values:

        <BYTE-STRING>
        <BYTE-VECTOR>
        <BUFFER>

        It is an error to call this function with START or END values
        outside of range(from: 0, through: size(BUFFER)).

COPY-FROM-BUFFER!  [Generic Function]

    Arguments
        destination :: <sequence>
        buffer :: <buffer>
        buffer-start :: <buffer-index>
        #key start :: <fixed-integer> = 0
        end :: <fixed-integer> = destination.size
    Values
        meaningless :: singleton(#f)
    Description
        Fills DESTINATION from START (defaults to zero) to END (defaults to
        the size of destination) with data from BUFFER that is taken
        starting at BUFFER-START.  Implementations are required to provide
        sealed methods for the following DESTINATION classes:

        <BYTE-STRING>
        <BYTE-VECTOR>
        <BUFFER>

        It is an error to call this function such that any attempt to index
        DESTINATION or BUFFER is out of bounds.  It is an error to call this
        function such that it attempts to index BUFFER elements in undefined
        ranges, as determined by the return values from GET-INPUT-BUFFER. It
        is an error for DESTINATION and BUFFER to be the same object. This
        function returns #f as a meaningless return value.

COPY-INTO-BUFFER!  [Generic Function]

    Arguments
        source :: <sequence>
        buffer :: <buffer>
        buffer-start :: <buffer-index>
        #key start :: <fixed-integer> = 0
        end :: <fixed-integer> = source.size
    Values
        meaningless :: singleton(#f)
    Description
        Fills BUFFER starting at BUFFER-START with elements taken from
        SOURCE from START (defaults to zero) to END (defaults to the size of
        SOURCE). Implementations are required to provide sealed methods for
        the following classes:

        <BYTE-STRING>
        <BYTE-VECTOR>
        <BUFFER>

        It is an error to call this function such that any attempt to index
        SOURCE or BUFFER is out of bounds. It is an error for DESTINATION
        and BUFFER to be the same object. This function returns #f as a
        meaningless return value.

10.  Conditions
---------------
The Streams library exports the following condition names and accessors:

<END-OF-FILE>

        The <END-OF-FILE> condition is a subclass of <ERROR>.  The recovery
        protocol is empty.  The make method takes the stream: keyword
        argument and stores the value in the condition object. The
        END-OF-FILE-STREAM function when called on an <END-OF-FILE> instance
        returns the value passed as the stream: argument to make. The stream
        object can be useful when reporting the condition to a user or
        distinguishing which stream ended when reading from more than one
        stream at a time.

<FILE-NOT-FOUND>

        The <FILE-NOT-FOUND> condition is a subclass of <ERROR>.  The
        recovery protocol is empty. The make method for <FILE-NOT-FOUND>
        takes the filename: keyword argument and stores the value in the
        condition object.  The FILE-NOT-FOUND-FILENAME function when called
        on a <FILE-NOT-FOUND> instance returns the value passed as the
        filename: argument to make.

<FILE-EXISTS>

        The <FILE-EXISTS> condition is a subclass of <ERROR>.  The recovery
        protocol is empty.  The make method takes the filename: keyword
        argument and stores the value in the condition object.  The
        FILE-EXISTS-FILENAME function when called on a <FILE-EXISTS>
        instance returns the value passed as the filename: argument to make.

11.  Footnotes
--------------

 1. The STREAM-EXTENSION-GET-INPUT-BUFFER function cannot guarantee to
    return a buffer with available input. Implementations will define the
    INPUTAVAILABLE? function in terms of checking the stream's buffer, and
    upon finding no available input there, then calling
    INPUT-AVAILABLE-AT-SOURCE?.  If STREAM-EXTENSION-GET-INPUT-BUFFER
    guaranteed returning a buffer with input available, then it might block
    getting that input. If STREAM-EXTENSION-GET-INPUT-BUFFER could block,
    then INPUTAVAILABLE? could not be defined in terms of the Stream
    Extension Protocol.
 2. The definition of READ-LINE is contingent on Dylan's resolution of
    handling newlines, and this function may have problems on some systems.
 3. ONE-OF returns a type expression that represents exactly the values
    passed in:

        define constant one-of =
          method (value, #rest more-values) => type :: <type>;
            reduce(union, singleton(value), map(singleton, more-values));
          end method;

 1. TYPE-OR returns a type expression that represents the union of all types
    passed in:

        define constant type-or =
          method (type :: <type>, #rest more-types) => type :: <type>;
            // Ensure more-types contains only types.
            do(rcurry(check-type, <type>), more-types);
            // Make a union of all types out of Dylan's binary union function.
            reduce(union, type, more-types);
          end method;

 1. We need these functions so that users can have reasonable semantics for
    copying to and from buffers.  There will likely be problems when
    implementations want to support <UNICODE-STRING> because copying
    unicode-string elements will take two buffer elements for each
    unicode-string element.  Ignoring extended character classes,
    COPY-SEQUENCE and REPLACE-SEQUENCE! have problems.  Using COPY-SEQUENCE
    requires wrapping the AS function around each call, and users have to
    hope their Dylan implementation does the right data flow analysis and
    source-level transforms to extract a sequence and create the right
    result type with exactly one allocation and one copying of the data.  If
    COPY-SEQUENCE took a result class, then users could assume this would
    happen in one action. Using REPLACE-SEQUENCE! has weird growth semantics
    which is inconsistent with this proposal's refusal to allow users to
    arbitrarily grow and replace a stream's buffer; this could be confusing
    to some users.  For example, users are surprisingly always baffled when
    they use Common Lisp's DELETE function, remove the first element of a
    list, and then cannot figure out why the result is not EQ to the
    argument (even though the documentation always warned against this
    assumption).
