[m-dev.] for review: stream I/O
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Oct 3 01:08:28 AEDT 2000
On 02-Oct-2000, Peter Ross <petdr at miscrit.be> wrote:
> On Mon, Oct 02, 2000 at 07:08:20PM +1100, Fergus Henderson wrote:
> > On 01-Oct-2000, Peter Ross <petdr at miscrit.be> wrote:
> > > + % Given a handle to a stream construct a unique stream object
> > > + % which can be used to do IO on the stream.
> > > + % This object initialises its state from the io__state.
> > > +:- pred stream__init(S::in, stream(S)::uo, io__state::di, io__state::uo) is det.
> > > +
> > > + % Tie the stream back into the io__state. Omitting this call
> > > + % may allow the compiler to optimize away the stream I/O.
> > > +:- pred stream__destroy(stream(S)::di, io__state::di, io__state::uo) is det.
> >
> > There are some nasty semantic problems with these routines.
> > At very least, the documentation is incomplete.
> > More likely the interface declared here won't work (i.e. can't be
> > implemented in a way that is logically sound and that matches
> > their intended semantics).
> >
> > The comment for `stream__destroy' explains its purpose, but
> > doesn't describe its effect. What are the declarative and
> > operational semantics of `stream__destroy'?
> >
> > In the case where there is no call to stream__destroy, the logically
> > correct behaviour is for there to be no side effects, [...]
>
> I understand the problem that you are pointing out here, and I would
> appreciate a possible solution.
Well, one possible approach is the one that I mentioned earlier:
instead of providing stream__init and stream__destroy,
provide `with_stream', which would be equivalent to
:- mode with_stream(in, pred(di, uo) is det, di, uo) is det.
with_stream(S0, Pred) -->
stream__init(S0, Stream0),
{ Pred(Stream0, Stream) },
stream__destroy(Stream).
The difference is that now it is not possible to have
any unmatched calls to stream__destroy. (The only exception
is the case when an exception is thrown, but since the final io__state
after try_io is unspecified, it doesn't matter what I/O the
implementation does in that case.)
However, that approach might limit expressiveness too much -- I'm not sure.
The with_stream/4 that I defined above doesn't let the predicate
have any output, except via side effects to the io__state.
So probably you want something like
:- mode with_stream(pred(out, di, uo) is det, out, di, uo) is det.
with_stream(Pred, Result, S0, S) -->
stream__init(S0, Stream0),
{ Pred(Result, Stream0, Stream) },
stream__destroy(Stream, S).
instead.
> The only solution that I can think of is to have two stream type
> classes, one which is side effect free and one which isn't.
> Here is the interface for the side effect streams.
>
> :- typeclass stream__input(S) where [
> pred stream__read_char(S, stream__result(char), io__state, io__state)
> mode stream__read_char(in, out, di, uo) is det
> ].
>
> where S must be a handle which is used to select the correct read
> character implementation.
That would work too. It depends on what you're trying to achieve.
That is a less ambitious design, more similar to the existing I/O
library; it just adds the possibility of user-defined stream types
(at the Mercury level) and provides genericity over the different
stream types. The other alternatives that we're discussing are
more radical changes: by splitting the io__state into sub-states
for different streams, they allow more parallelism/concurrency, and
are arguably a more elegant design, but this comes at a cost of
increased complexity (e.g. the need to lock files, for the
deterministic parallelism case, or the unspecified order of
side effects, for the `cc_multi' concurrent case.).
These approaches don't have to be mutually exclusive, of course.
There may be a case for providing all three:
- one to use when you care about the order of side effects
- one to use when you don't care about the order of side
effects, even though they may influence the result
- one to use when you know that the order of side effects
won't influence the result
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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