[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue: STANDARD-INPUT-INITIAL-BINDING (version 4)



Issue:         STANDARD-INPUT-INITIAL-BINDING
References:    Standard streams (pp. 327-329)
Category:      CHANGE
Edit history:  Version 1 by Pierson and Haflich 1/19/87
    	       Version 2 by Pierson 2/29/88
	       Version 3 by Pierson 5/23/88, per comments by Moon
               Version 4 by Pierson 5/26/88, clean up
Status:        For Internal Discussion

The primitive streams have been removed, completely this time.

Problem description:

CLtL requires that *STANDARD-INPUT*, *STANDARD-OUTPUT*,
*ERROR-OUTPUT*, *TRACE-OUTPUT*, *QUERY-IO*, and *DEBUG-IO* are
initially bound to synonym streams to *TERMINAL-IO*.  This requirement
hampers the integration of Common Lisp with many existing and
potential operating environments.

For example, a Unix implementation is currently unable to legally
support Unix standard error output even though Common Lisp defines
*ERROR-OUTPUT* because *ERROR-OUTPUT* is required to start out bound
to the same stream as *STANDARD-OUTPUT*.  A workstation environnment
which provides stream access to windows as an extension is currently
forbidden to make trace output appear in a separate window by default
because *TRACE-OUTPUT* is required to start out bound to the same
stream as *STANDARD-OUTPUT*.

Proposal (STANDARD-INPUT-INITIAL-BINDING:DEFINED-CONTRACTS):

A Common Lisp implementation is required to provide the following
initial streams.  Each initial stream has a specific purpose as defined
in CLtL.

    *STANDARD-INPUT*
    	This stream is bound to the primary default input of the Lisp
	process (e.g. standard input on Unix, SYS$INPUT on VMS).  While
	this will probably be an interactive terminal or window during
	program development, it may well be a data file for a
	non-interactive application.
    *STANDARD-OUTPUT*
    	This stream is bound to the primary default output of the Lisp
	process (e.g. standard output on Unix, SYS$OUTPUT on VMS).  While
	this will probably be an interactive terminal or window during
	program development, it may well be a data file for a
	non-interactive application.
    *QUERY-INPUT*
    	Whenever possible, this stream is bound to an interactive
	input source.  This may be the same as *STANDARD-INPUT* in a
	development environment, or it may be a separate window, or
	terminal.  If the Lisp system is running under an operating
	system such as Aegis which provides a separate error input
	source, this stream should probably be bound to that source.
	In a non-interactive environment for which no interactive input
	is available, reading this stream will always result in EOF.
    *ERROR-OUTPUT*
    	If *QUERY-INPUT* is bound to an interactive input source, this
	stream should be bound to the cooresponding interactive output
	destination.  If the Lisp system is running under an operating
	system such as Aegis, Unix, or VMS which provides a separate
	error output destination, this stream should be bound to that
	destination.  In a non-interactive environment without a
	separate error destination, this stream should be bound to the
	same destination as *STANDARD-OUTPUT*.
    *TRACE-OUTPUT*
    	The initial binding of *TRACE-OUTPUT* is *ERROR-OUTPUT*
	in a non-windowed environment.  In a windowed environment,
    	*TRACE-OUTPUT* may start out bound in some other way (e.g. to
	a non-existant trace output window which will be automatically
	created when output is first done to *TRACE-OUTPUT*).
    *QUERY-IO*
        In a non-windowed environment, the initial binding of
    	*QUERY-IO* is a stream that reads from *QUERY-INPUT*
        and writes to *ERROR-OUTPUT*.
    *TERMINAL-IO*
    	The initial binding of *TERMINAL-IO* is the same as *QUERY-IO*
	in a non-windowed environment.  In a windowed environment,
	*TERMINAL-IO* may refer to a different window than *QUERY-IO*
	as long as all of these streams refer to windows.
    *DEBUG-IO*
    	The initial binding of *DEBUG-IO* is the same as *QUERY-IO* in
	a non-windowed environment.  In a windowed environment,
	*DEBUG-IO* may refer to a different window than *QUERY-IO*
	as long as all of these streams refer to windows.

Test Cases/Examples:

(PROGN
   (PRINT "Output" *STANDARD-OUTPUT*)
   (PRINT "Error" *STANDARD-ERROR*))

In current Common Lisp will write:
------
Output
Error
------

With proposal *might* write:
------
Output
------
and "Error" appears somewhere else.

Rationale:

This proposal attempts to provide a balance between over-specifying
behavior to the point that Lisp programs can't behave like other
programs in conventional operating systems and providing enough
specification that Common Lisp programs can perform portable input and
output.

Current practice:

Lucid binds *TERMINAL-IO* to a special internal stream type.  Franz
binds *TERMINAL-IO* to a special internal stream type for terminal
streams which reads from Unix standard input and writes to Unix
standard output.  KCL binds *TERMINAL-IO* to a standard two-way-stream
with input from Unix standard input and output to Unix standard
output.

Cost to Implementors:

All implementations will have to change to some degree but the changes
will probably be simple and localized.

Cost to Users:

User code which depends on the strict binding hierarchy in CLtL may
have to change.  

Cost of non-Adoption:

It will continue to be difficult or impossible to integrate portable
Common Lisp progams in conventional operating system environments.
Many implementations will have to continue to choose between
conforming to the standard and providing a superior user environment.

Benefits:

Implementations will be more able to match their IO behavior to their
environment and their user's expectations.  

Aesthetics:

Slightly improved because this area becomes better defined.

Discussion:

The repeated mention of windowing environments above seems to be
getting dangerously close to the environmental issues this standard is
supposed to avoid, but Pierson feels that if we have to do more than
leave these areas undefined, we also have to give advanced
environments official permission to do their thing.

Pitman was concerned that the initial version of this proposal didn't
provide a guaranteed way to get back the initial streams after
rebinding, e.g. *standard-io*.  The second version of this proposal
offered a solution to that problem which was generally considered too
complex.

Moon says that *TERMINAL-IO* (and, by extension, *QUERY-IO*, and
*DEBUG-IO*) should fail to work in a non-interactive environment where
nothing like a terminal exists.  While this version partially
implements Moon's view by expressing all of these in terms of
*QUERY-INPUT* and *ERROR-OUTPUT* and requiring *QUERY-INPUT* to return
EOF in a non-interactive environment, this view is controversial.
Pierson is currently neutral on this question.

Masinter notes that:
    ``In many multi-processing multi-window environments,
      the "initial binding" for *STANDARD-INPUT*, *QUERY-INPUT*
      differs for each process.''  
This proposal provides very weak support for such environments by
refering to "the Lisp process" rather than "the Lisp system" when
defining *STANDARD-OUTPUT* and *STANDARD-INPUT*.  Some additional
verbiage may be needed to cover this case.