[m-dev.] for review: stream I/O
Ralph Becket
rbeck at microsoft.com
Tue Oct 3 01:00:10 AEDT 2000
>From Michael Day on 02/10/2000 13:49:26
>
> I
> considered a number of wrapper predicates that take an io__state pair as
> well as a stream pair to enforce total ordering for those cases when you
> really need it, I assume that wouldn't be too hard to add.
I may not have access to the io__state where I want this behaviour; the
idea of having to pass in the io__state whenever I just want a total order
on the operations of some non-io streams seems something of a hack to me.
> <looks blank, searches for meaning of conflated in nearby dictionary>
Conflate: to combine two or more things into a whole.
As I understand it, what is currently being proposed conflates the
following two ideas:
1. the state object being manipulated; and
2. a parameter (`handle') indicating how a particular operation should
affect a state object.
In many cases, the handle parameter is left implicit (e.g. the current io
library writes to stdout and reads from stdin by default).
As I see it, for a state object to be a stream, it has to have (one of)
read_char/3 and write_char/3 as methods with a default `handle' (actually
I probably want a whole host of other methods as standard with a library
providing default implementations.)
For io__states this is straightforward and one can set up the `handle'
with io__see/seen/tell/told. Forking off separate IO streams from the
io__state is going to cause trouble (e.g. cc_multi's all over the shop.)
Also, I don't see why I need to involve the io__state when I'm setting up,
say, a string stream.
So this is mainly a criticism of the stream.m module, or rather
stream__init/4. stream.m provides (a) a means of adding a putback buffer
to a stream and (b) some handy predicates over streams.
(a) is a bit arbitrary - e.g. what about seekable streams? I would rather
see the interface changed to include
:- typeclass putback_stream(S) <= input_stream(S) where [
pred putback_char(char::in, S::di, S::uo) is det
].
and do away with stream__putback_char/3.
One could then provide a convenience wrapper type
:- type putback_stream(S) == {list(char), S}.
:- instance putback_stream(putback_stream(S)) where [
putback_char(Char, {Chars, Strm}, {[Char | Chars], Strm})
].
:- instance input_stream(putback_stream(S)) <= input_stream(S) where [
( read_char(Result, {Chars0, Strm0}, {Chars, Strm}) :-
( Chars0 = [Char | Chars],
Result = ok(Char),
Strm = Strm0
;
Chars0 = [],
Chars = [],
read_char(Result, Strm0, Strm)
)
)
].
The other predicates in stream.m aren't really stream__stream
specific.
As I say, I'd rather have an higher level stream abstraction which
included stuff like read_word/line, ignore_whitespace etc. as
methods since (a) we're going to provide default method implementations
RSN (so I'm told (except for the RSN bit :)) and (b) a stream
implementation should be free to use more efficient methods than the
default implementations (e.g. clever buffering & read-ahead).
Ralph
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list