On Thursday, 25 June 2020 at 03:35:00 UTC, repr-man wrote:


This seems to have to do with the fact that all iterators return their own unique type. Could someone help me understand the reason behind this design and how to remedy my situation?

Ranges conform to well-defined interfaces. Given that the algorithms in Phobos are templates and use structs rather than classes, this means the interfaces are checked at compile time (see the `is*` templates in std.range.primitives [1]). It also means that there is no concrete range "type" returned by these functions. That's why all of them return `auto` instead of a specific type. You never need to know the specific type of a range.

Arrays are ranges only because of the free-function implementation of the range interfaces in std.range.primitives which all take an array as the first argument so that they may be called using UFCS in any templated range algorithm.

So when you input an array to a range algorithm, the algorithm has no idea it has an array. It just calls R.emtpy, R.front, etc., without ever caring what the actual type is. And you can chain them because each algorithm wraps the input range with custom range type that actually implements the algorithm (in e.g., `popFront`--that's also why ranges are lazy), and that's what is returned. In a chain of function calls, popFront is called on the outermost range, which calls popFront on its wrapped range, which calls popFront on its wrapped range, etc. So if you append std.array.array to the end of the chain, it will kick off execution of the whole chain of calls by making the first call to popFront in order to copy the result into a new array.

Chapter 6, "Understanding Ranges", from "Learning D" is available freely online [2]. You should give it a read.


[1] https://dlang.org/phobos/std_range_primitives.html
[2] https://hub.packtpub.com/understanding-ranges/

Reply via email to