Segmented Ranges?

bearophile bearophileHUGS at lycos.com
Sun Jun 17 08:46:40 PDT 2012


Andrei Alexandrescu:

> Would joiner help?

I don't know. I think the point of those segmented ranges is to 
not hide their segmented nature (as joiner does).

- - - - - - - - - - - - - -

This paper shows a variant of the stream fusion, applied on 
chunked arrays that represent strings:

"Rewriting Haskell Strings" (2007) by Duncan Coutts, Don Stewart, 
Roman Leshchinskiy:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.3166


In D it's easy to create a range that segments a given lazy range 
into a lazy iterable of arrays:


import std.range: ElementType;
import std.array: empty, front, popFront;

struct Segmenter(size_t chunkLength, Range) {
     alias ElementType!Range elementT;
     private elementT[chunkLength] chunk;
     private Range r;
     private size_t len;

     this(Range rin) {
         this.r = rin;
         popFront();
     }

     @property bool empty() const {
         return len == 0 && r.empty;
     }

     @property elementT[] front() pure nothrow {
         return chunk[0 .. len];
     }

     void popFront() {
         len = 0;
         while (len < chunkLength && !r.empty) {
             chunk[len] = r.front;
             len++;
             r.popFront();
         }
     }
}


But Phobos ranges don't manage segments automatically (so you 
can't just apply a normal map on a Segmenter, because this map 
will work on the chunks), and there aren't the optimizations 
described in that paper. On the other hand some range methods 
become inlined, because D ranges are quite different from Haskell 
lazy lists, so maybe some of those optimizations are not needed.

Bye,
bearophile


More information about the Digitalmars-d mailing list