On Sunday, 4 December 2016 at 11:50:08 UTC, Mike Parker wrote:
On Sunday, 4 December 2016 at 11:18:56 UTC, rumbu wrote:



Of course, the previous code will compile if we change the imports: import std.range.primitives: isInputRange, front, popFront, empty;

But that just prove the bad design of isInputRange which cannot be used all alone without the rest of array UFCSs imported.

isInputRange can be used alone just fine. But you aren't using it alone.

 I'm using it all alone:

auto first(R)(R range) if (isInputRange!R)
{
  return range.front;
  //compile time error when calling first!string
}

auto first(C)(const(C)[] str)
{
   return str[0];
   //never called;
}

first(someString);

You're using it together with the range primitives for arrays, but you are explicitly excluding them from the import by only selectively importing isInputRange. The import is working exactly as advertised. What is it about this case that makes you think it should behave differently?

Advertising from the docs says this: "An input range must define the primitives empty, popFront, and front." In my module context, I didn't define any of them, isInputRange!string must return false, because string is not a range, I repeat - *in my module context*. There is nowhere in the documentation where arrays are advertised as ranges by default.

If I copy the isInputRange definition in my module, it will clearly return false:

import std.range.primitives: isInputRange;
template isInputRange2(R)
{
    enum bool isInputRange2 = is(typeof(
    (inout int = 0)
    {
        R r = R.init;     // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront();     // can invoke popFront()
        auto h = r.front; // can get the front of the range
    }));
}


static assert(isInputRange!string); //wrong!
static assert(!isInputRange2!string); //correct!

I think that the array range UFCSs must be moved out from the std.range.primitives and let the library user to decide if there is a need for range semantics applied to all arrays.

Otherwise, as long as you want array specializations for your functions, you must decorate all the range specializations with (isInputRange!T && !isArray!T). And you are compelled to use "f(T)(T t) if isArray!T" for all your array specializations instead of "f(T)(T[] x)".







Reply via email to