wrong isInputRange design
rumbu via Digitalmars-d
digitalmars-d at puremagic.com
Sun Dec 4 05:37:35 PST 2016
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)".
More information about the Digitalmars-d
mailing list