[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Another "T style" question
Date: Tue, 30 Aug 83 23:54:33 EDT
From: Jim Meehan <Meehan>
Re: Another "T style" question
Topic: Explicit versus implicit streams. In T, one must always specify
the stream to routines such as READ and PRINT. An alternative approach
would be to establish a "currently open input stream" and "currently
open output stream"; the "stream" parameter to READ, PRINT, et al.,
would then be omitted, as in ur-LISP, or made an optional parameter.
Advantages to explicit streams: You always know where the I/O is coming
from (going to) instead of relying on the kindness of strange routines
that might have switched streams before you got called. The overhead
for a fixed number of parameters may be less than for "lexprs."
Advantages to implicit streams: You write less. The overhead in
checking the legitimacy of a stream is paid once, at stream-selection
time, rather than every time you refer to the stream in a READ or PRINT
statement. If you DO specify a stream, then presumably the current
stream has to be saved and restored around your call; i.e., there's
a penalty for being explicit when the default is to be implicit.
The plan is to one day make the stream argument be optional for
most of the I/O procedures which take a final stream argument. The
stream argument would default to (STANDARD-INPUT) or (STANDARD-OUTPUT),
so that (PRINT X) would reliably mean the same thing as
(PRINT X (STANDARD-OUTPUT)) [modulo shadowings of the names PRINT and
STANDARD-OUTPUT, of course].
This change will happen when it can be implemented efficiently. Calling
"lexprs" is not more expensive than calling anything else, but entering
them usually causes the rest-argument to be consed in the heap, which is
not good. Internally, everything will remain explicit, since global
state almost always leads to awful bugs, and I don't think there are any
particular performance advantages. There is still some of this lurking
around in the implementation, however, and I eliminate it whenever I get
an opportunity. I have regretted using global state (i.e. BIND and SET)
each time I have done so.
This is different from what you suggest because it reduces the implicit
case to the explicit one and not vice-versa, which I think would be
a mistake. It would NOT be the case that (PRINT X STREAM) was the
same as (BIND (((STANDARD-OUTPUT) STREAM)) (PRINT X)).
Etc. Of course, this applies to other global/local issues as well,
such as input/output radix for numbers, where T takes the implicit
approach.
I don't quite understand this, since there is no released way for users
to manipulate the i/o radices. The plan for the future is to make a
radix be a component of read-tables. Note that read-tables are never
implicit in the way you suggest either, since they are always either
explicitly passed to READ-OBJECT or fetched from the stream by READ's
default method before it calls READ-OBJECT.
As far as I know, all of the system's global state is, at least in
theory, confined to the stream and user interface switches
foo-INPUT/OUTPUT, REPL-foo, and a few peripheral others. I will do
everything I can to eliminate RECKLESSNESS, which I believe can be made
at least lexical if not explicit.