21.1 Standard Streams

There are several variables whose values are streams used by many functions in the Lisp system. These variables and their uses are listed here. By convention, variables that are expected to hold a stream capable of input have names ending with -input, and variables that are expected to hold a stream capable of output have names ending with -output. Variables expected to hold a bidirectional stream have names ending with -io.

[Variable] *standard-input*

In the normal Lisp top-level loop, input is read from *standard-input* (that is, whatever stream is the value of the global variable *standard-input*). Many input functions, including read and read-char, take a stream argument that defaults to *standard-input*.


[Variable] *standard-output*

In the normal Lisp top-level loop, output is sent to *standard-output* (that is, whatever stream is the value of the global variable *standard-output*). Many output functions, including print and write-char, take a stream argument that defaults to *standard-output*.


[Variable] *error-output*

The value of *error-output* is a stream to which error messages should be sent. Normally this is the same as *standard-output*, but *standard-output* might be bound to a file and *error-output* left going to the terminal or to a separate file of error messages.


[Variable] *query-io*

The value of *query-io* is a stream to be used when asking questions of the user. The question should be output to this stream, and the answer read from it. When the normal input to a program may be coming from a file, questions such as “Do you really want to delete all of the files in your directory?” should nevertheless be sent directly to the user; and the answer should come from the user, not from the data file. For such purposes *query-io* should be used instead of *standard-input* and *standard-output*. *query-io* is used by such functions as yes-or-no-p.


[Variable] *debug-io*

The value of *debug-io* is a stream to be used for interactive debugging purposes. This is often the same as the value of *query-io*, but need not be.


[Variable] *terminal-io*

The value of *terminal-io* is ordinarily the stream that connects to the user’s console. Typically, writing to this stream would cause the output to appear on a display screen, for example, and reading from the stream would accept input from a keyboard.

It is intended that standard input functions such as read and read-char, when used with this stream, would cause “echoing” of the input into the output side of the stream. (The means by which this is accomplished are of course highly implementation-dependent.)


[Variable] *trace-output*

The value of *trace-output* is the stream on which the trace function prints its output.


The variables *standard-input*, *standard-output*, *error-output*, *trace-output*, *query-io*, and *debug-io* are initially bound to synonym streams that pass all operations on to the stream that is the value of *terminal-io*. (See make-synonym-stream.) Thus any operations performed on those streams will go to the terminal.

X3J13 voted in January 1989 to replace the requirements of the preceding paragraph with the following new requirements:

The seven standard stream variables, *standard-input*, *standard-output*, *query-io*, *debug-io*, *terminal-io*, *error-output*, and *trace-output*, are initially bound to open streams. (These will be called the standard initial streams.)

The streams that are the initial values of *standard-input*, *query-io*, *debug-io*, and *terminal-io* must support input.

The streams that are the initial values of *standard-output*, *error-output*, *trace-output*, *query-io*, *debug-io*, and *terminal-io* must support output.

None of the standard initial streams (including the one to which *terminal-io* is initially bound) may be a synonym, either directly or indirectly, for any of the standard stream variables except *terminal-io*. For example, the initial value of *trace-output* may be a synonym stream for *terminal-io* but not a synonym stream for *standard-output* or *query-io*. (These are examples of direct synonyms.) As another example, *query-io* may be a two-way stream or echo stream whose input component is a synonym for *terminal-io*, but its input component may not be a synonym for *standard-input* or *debug-io*. (These are examples of indirect synonyms.)

Any or all of the standard initial streams may be direct or indirect synonyms for one or more common implementation-dependent streams. For example, the standard initial streams might all be synonym streams (or two-way or echo streams whose components are synonym streams) to a pair of hidden terminal input and output streams maintained by the implementation.

Part of the intent of these rules is to ensure that it is always safe to bind any standard stream variable to the value of any other standard stream variable (that is, unworkable circularities are avoided) without unduly restricting implementation flexibility.

No user program should ever change the value of *terminal-io*. A program that wants (for example) to divert output to a file should do so by binding the value of *standard-output*; that way error messages sent to *error-output* can still get to the user by going through *terminal-io*, which is usually what is desired.