D's Auto Decoding and You

Steven Schveighoffer via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Thu May 19 06:21:40 PDT 2016


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
>>> @property.
>>
>> 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
> recently?

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

-Steve


More information about the Digitalmars-d-announce mailing list