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