On Friday, 17 November 2017 at 01:16:38 UTC, H. S. Teoh wrote:


It should be .empty, .popFront, and .front, not .pop.

Also, these methods are *range* primitives, and over time, we have come to a consensus that generally speaking, it's a bad idea to conflate containers with ranges over containers. The main thing is that iterating over a range is supposed to consume it, which is usually not what you want with a container.

The usual idiom is to separate the two concepts, and have the container provide a mechanism for returning a range over its contents, usually via .opIndex with no arguments, or .opSlice. Then you would just write:

        foreach (e; myContainer[]) { // [] calls .opIndex/.opSlice
                ...
        }

Unfortunately, built-in arrays, which are also ranges, are one exception to this rule that, due to their ubiquity in D, also serve to mislead newcomers to D about when/where range primitives should be implemented. Generally speaking, built-in arrays should not be considered exemplary in this respect, but rather should be understood as exceptions. The general convention is to separate your containers from ranges over its contents, and to provide .opIndex / .opSlice that constructs a range over the container when needed.

The other consideration is that if you don't really need range functionality, i.e., the only thing you want to do with your container is to put it in a foreach loop, then you can sidestep this whole mess and just implement .opApply for your container and call it a day. Of course, then you won't be able to use generic algorithms like those in std.algorithm with your container, but if you didn't intend to anyway, it's not a big deal.


T

Thanks T! Good information, especially "iterating over a range is supposed to consume it". I have been reading dlang.org->Documentation->Language Reference, but should have also read dlang.org->Dlang-Tour->Ranges. Although that page 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.

Reply via email to