Streams, growing sequences, and object identity

When writing to output streams over sequences, Dylan may from time to time need to grow the underlying sequence that it is using to represent the stream data.

Consider the example of an output stream instantiated over an empty string. As soon as a write operation is performed on the stream, it is necessary to replace the string object used in the representation of the string stream. As well as incurring the cost of creating a new string, the replacement operation can affect the integrity of other references to the string within the program.

To guarantee that alias references to a sequence used in an output <sequence-stream> will have access to any elements written to the sequence via the stream, supply a <stretchy-vector> to make. A stream over a stretchy vector will use the same stretchy vector throughout the stream's existence.

For example:

let sv = make(<stretchy-vector>);
let stream = make(<sequence-stream>, 
                  contents: sv, 
                  direction: #"output");
write(stream, #(1, 2, 3, 4, 5, 6, 7, 8, 9));
write(stream, "ABCDEF");
values(sv, stream-contents(stream));

The example returns two values. Each value is the same (\==) stretchy vector:

#[1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']

If a stretchy vector is not supplied, the result is different:

let v = make(<vector>, size: 5);
let stream = make(<sequence-stream>,
                  contents: v, 
                  direction: #"output");
write(stream, #(1, 2, 3, 4, 5, 6, 7, 8, 9));
write(stream, "ABCDEF");
values(v, stream-contents(stream));

This example returns as its first value the original vector, whose contents are undefined, but the second value is a new vector:

#[1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']

This difference arises because the output stream in the second example does not use a stretchy vector to hold the stream data. A vector of at least 15 elements is necessary to accommodate the elements written to the stream, but the vector supplied, v, can hold only 5. Since the stream cannot change v's size, it must allocate a new vector each time it grows.