On 5/17/16 8:36 PM, H. S. Teoh via Digitalmars-d-announce wrote:
On Tue, May 17, 2016 at 08:19:48PM +0000, Vladimir Panteleev via 
Digitalmars-d-announce wrote:
On Tuesday, 17 May 2016 at 17:26:59 UTC, Steven Schveighoffer wrote:
However, it's perfectly legal for a front function not to be tagged

BTW, where is this coming from? Is it simply an emergent property of
the existing implementations of isInputRange and ElementType, or is it
actually by design?

This is very bad. The range API does not mandate that .front must be a
function. I often write ranges where .front is an actual struct variable
that gets updated by .popFront.  Now you're saying that my range won't
work with some code, because they call .front() (which is a compile
error when .front is a variable, not a function)?

My goodness no!

People, please, my point is simply that is(typeof(someRange.front) == ElementType!(typeof(someRange))) DOESN'T ALWAYS WORK.

Here is the (long standing) definition of isInputRange:

template isInputRange(R)
    enum bool isInputRange = 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

Not there is no check for is(typeof(r.front)) to be some certain thing.

So this is a valid range:

struct AllZeros
    int front() { return 0; }
    enum empty = false;
    void popFront() {}

Yet, is(typeof(AllZeros.init.front) == int) will be false. This is the line of code from the article that I suggested to add the parens to. Because in that particular case, string.front is a function, not a field. The code in question is NOT GENERIC, it's just showing that string.front is not the same as string[0]. It's very specific to string.

In the old days (i.e., 1-2 years ago), isForwardRange!R will return
false if .save is not marked @property. I thought isInputRange!R did the
same for .front, or am I imagining things?  Did somebody change this

You are imagining that someInputRange.front ever required that. In fact, it would have had to go out of its way to do so (because isInputRange puts no requirements on the *type* of front, except that it returns a non-void value).

But you are right that save did require @property at one time. Not (In my opinion) because it meant to, but because it happened to check the type of r.save against a type (namely, that .save returns its own type).

At the same time, I fixed all the isXXXRange traits so @property is not required anywhere. In particular, isRandomAccessRange required r.front to be @property, even when isInputRange didn't (again, IMO unintentionally). Here is the PR: https://github.com/dlang/phobos/pull/3276


Reply via email to