stream == range ? [Sliding window]
Dmitry Olshansky via Digitalmars-d
digitalmars-d at puremagic.com
Sun May 31 14:50:28 PDT 2015
On 01-Jun-2015 00:18, Mafi wrote:
> On Sunday, 31 May 2015 at 17:50:41 UTC, Dmitry Olshansky wrote:
>
>>
>> 2. If we were to reuse algorithms - most algorithms love ForwardRange.
>> And there is a problem implementing it for streams in the _range_ API
>> itself.
>>
>> Yeah, most streams are seekable like e.g. files or MM-files, so they
>> must be ForwardRanges... And indeed saving position is trivial.
>>
>> Now look at the signature for ForwardRange:
>> struct Range{
>> ...
>> @property Range save();
>> }
>>
>> Yeah, you'd gotta duplicate the whole stream to count as ForwardRange.
>> Yicks! Signatures that might work are:
>>
>> Mark save();
>> void restore(Mark m);
>>
>
> I think here you confuse typical Range semantics with the semantics of
> the most prominent but also most akward Range implementation: dynamic
> arrays. In my opinion the signature of 'save' for ForwardRanges is good.
I'm quite certain I'm talking of something beyond dynamic arrays -
buffered I/O much like D's std.stdio File wrapper of C's FILE I/O.
> With most ranges the 'mark' of yours is already embedded inside the
> range type and manipulated with 'popFront' (and 'popBack'). Other range
> data is most probably stored with indirection so copying it is no harm.
> As an example there is std.container.SList which is not a range. SList[]
> returning SList.Range is. It references its SList without owning it and
> therefore can be copied at will without touching the original SList.
Ranges were designed with algorithms and containers in mind. Current I/O
ranges were fitted in with a bit of strain and overhead.
> I cannot think of a stream that deserves to be a ForwardRange but is
> incompatible with this range pattern. Raw file handles cannot be
> ForwardRanges because multiple aliasing ranges would cause incorrect
> results.
The idea of reading raw file handles 1 byte at a time just to fit
InputRange interface is hilarious. What is an algorithm that *anyone* in
the right state of mind would want to run on raw file handle using such
interface?
Also it makes sense to accommodate a better set of primitives for raw
I/O, including support for scatter-gather read/write. And we wouldn't
have to constraining ourselves with stupid things like bool empty() -
that no one knows for sure until we read that file, pipe, socket...
On the other hand saving the state of a buffered stream is doable but
using the same type is unfortunate restriction.
>
> Your proposed signatures wouldn't help either. An inefficient
> file handle wrapper could be a correct ForwardRange if it seeks some
> defined position before every read operation. But again this would mean
> embedding this 'mark' inside the range.
I'm talking about buffered stuff obviously.
Also e.g. in memory-mapped file is trivial to save a position, and it
wouldn't require mapping all at once.
Speaking of InputRange as unbuffered stream, I'll refine my reply to
Andrei with more facts.
That range jacket simply doesn't fit:
- it requires buffering 1 element (front)
- requires primitives that are impossible to decently implement (e.g.
empty)
- convincingly suggest primitives that are anti-pattern in I/O: a
syscall per 1-element read? (at best)
Unbuffered I/O doesn't work like 3 separate things "peek, advance and
test for empty" troika. Otherwise I'm all for design by introspection
realization, it's just that I/O needs its own foundations.
--
Dmitry Olshansky
More information about the Digitalmars-d
mailing list