On 6/7/17 9:57 PM, Andrew Edwards wrote:
Ranges may be finite or infinite but, while the destination may be
unreachable, we can definitely tell how far we've traveled. So why
doesn't this work?

import std.traits;
import std.range;

void main()
{
    string[string] aa;

    // what others have referred to as
    // standard sort works but is deprecated
    //auto keys = aa.keys.sort;

    // Error: cannot infer argument types, expected 1 argument, not 2
    import std.algorithm: sort;
    auto keys = aa.keys.sort();

    // this works but why should I have to?
    //import std.array: array;
    //auto keys = aa.keys.sort().array;

    foreach (i, v; keys){}
}

If I hand you a chihuahua for grooming, why am I getting back a pit
bull? I simply want a groomed chihuahua. Why do I need to consult a
wizard to get back a groomed chihuahua?

The issue here is that arrays are special. Arrays allow foreach(i, v; arr) and foreach(v; arr). Ranges in general do not. So there is no way to forward this capability via the range interface. Not only that, but foreach(i, v; arr) is much different than iterating even a range that returns a tuple in that the index is *specific to the loop* and doesn't involve the array at all. It's more similar to opApply.

opApply can help, but still is different than how arrays work (foreach with array is handled directly by the compiler). But ranges are not going to be forwarding this feature just for arrays.

In answer to your question, if we returned something that *didn't* take advantage of the fact that the range is now sorted, then people who want that functionality (e.g. builtin binary search) would be complaining.

As a recommendation, I suggest you get used to using enumerate, as it will work for all cases of ranges, including arrays.

-Steve

Reply via email to