On Friday, 17 November 2017 at 07:40:35 UTC, Mike Parker wrote:


You might also find use in this article (poorly adapted from Chapter 6 of Learning D by the publisher, but still readable):

https://www.packtpub.com/books/content/understanding-ranges

makes a distinction about "range consumption" with regard to a "reference type" or a "value type" and it isn't clear to me why there would be a difference.

With a value type, you're consuming a copy of the original range, so you can reuse it after. With a reference type, you're consuming the original range and therefore can't reuse it.


========
struct ValRange {
    int[] items;
    bool empty() @property { return items.length == 0; }
    int front() @property { return items[0]; }
    void popFront() { items = items[1 .. $]; }
}

class RefRange {
    int[] items;
    this(int[] src) { items = src; }
    bool empty() @property { return items.length == 0; }
    int front() @property { return items[0]; }
    void popFront() { items = items[1 .. $]; }
}

void main() {
    import std.stdio;

    int[] ints = [1, 2, 3];
    auto valRange = ValRange(ints);

    writeln("Val 1st Run:");
    foreach(i; valRange) writeln(i);
    assert(!valRange.empty);

    writeln("Val 2nd Run:");
    foreach(i; valRange) writeln(i);
    assert(!valRange.empty);

    auto refRange = new RefRange(ints);

    writeln("Ref 1st Run:");
    foreach(i; refRange) writeln(i);
    assert(refRange.empty);

    writeln("Ref 2nd Run:");
    foreach(i; refRange) writeln(i); // prints nothing
}

Thanks for the reference and the code. I will have to iterate over the packpub text a while consulting the docs. I see that the code runs as you say, but I don't understand what's going on. You say with regard to a "value type" : "you're consuming a copy of the original range" but I don't see anything different between the processing in the struct versus in the class. They both have a dynamic array variable that they re-assign a "slice" to (or maybe that is - that they modify to be the sliced version). Anyway, I can't see why the one in the struct shrinks and then goes back to what it was originally. It's like calls were made by the compiler that aren't shown.

Reply via email to