May 17, 2016
On 5/17/16 1:49 PM, Rory McGuire via Digitalmars-d-announce wrote:
>
> On 17 May 2016 16:21, "Steven Schveighoffer via Digitalmars-d-announce"
> <digitalmars-d-announce@puremagic.com
> <mailto:digitalmars-d-announce@puremagic.com>> wrote:
>  >
>  > On 5/17/16 10:06 AM, Jack Stouffer wrote:
>  >>
>  >> http://jackstouffer.com/blog/d_auto_decoding_and_you.html
>  >>
>  >> Based on the recent thread in General, I wrote this blog post that's
>  >> designed to be part beginner tutorial, part objective record of the
>  >> debate over it, and finally my opinions on the matter.
>  >>
>  >> When I first learned about auto-decoding, I was kinda miffed that there
>  >> wasn't anything in the docs or on the website that went into more
>  >> detail. So I wrote this in order to introduce people who are getting
>  >> into D to the concept, it's benefits, and downsides. When people are
>  >> confused in Learn why typeof(s.front) == dchar then this can just be
>  >> linked to them.
>  >>
>  >> If you think there should be any more information included in the
>  >> article, please let me know so I can add it.
>  >
>  >
>  > Starting to read it, see errors in your examples:
>  >
>  > is(s[0] == immutable char) -> is(typeof(s[0]) == immutable(char))
>  > is(s.front == dchar) -> is(typeof(s.front()) == dchar)
>  >
>  > I'm not sure if you need the parens after front, but if it's not
> marked as @property, then this returns a function.
>  >
>
> If I remember correctly adding the brackets then goes against best
> practices because you can't be sure the underlying implementation of a
> range is using a function for .front.
>

Right, but there's this:

struct MyRange
{
   private int _val;
   int front() { return _val; }
   bool empty() { return _val < 100; }
   void popFront() { ++_val; }
}

static assert(isInputRange!MyRange);
static assert(!is(typeof(MyRange.init.front) == int));

This is why I recommended the parentheses. In reality, you should do ElementType!MyRange, which does the correct thing. But is(typeof(...)) doesn't always work like you might expect.

-Steve
May 17, 2016
On 5/17/16 2:23 PM, Vladimir Panteleev wrote:
> On Tuesday, 17 May 2016 at 17:26:59 UTC, Steven Schveighoffer wrote:
>> On 5/17/16 1:18 PM, Vladimir Panteleev wrote:
>>> On Tuesday, 17 May 2016 at 14:06:37 UTC, Jack Stouffer wrote:
>>>> http://jackstouffer.com/blog/d_auto_decoding_and_you.html
>>>
>>> Thanks for writing this. Great article.
>>>
>>> Some remarks:
>>>
>>>>    static assert(is(typeof(s.front()) == dchar));
>>>
>>> I believe .front is a property (so some ranges can implement it as a
>>> field, not a @property function). Hence, no parens.
>>
>> Right, but s is a string. So front is a function.
>
> Then what happened to writing generic code?

This isn't generic code, it's just demonstrating that string's front does not yield immutable(char). It's very specific to string.

In my recommendation to add the parens, I wasn't sure if front is marked @property or not.

In any case, this is a lot of conversation about something that isn't that important :)

-Steve
May 17, 2016
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?
May 17, 2016
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)?

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?


T

-- 
INTEL = Only half of "intelligence".
May 17, 2016
On Tue, May 17, 2016 at 02:06:37PM +0000, Jack Stouffer via Digitalmars-d-announce wrote:
> http://jackstouffer.com/blog/d_auto_decoding_and_you.html
[...]

Thanks for writing up this article!


T

-- 
What did the alien say to Schubert? "Take me to your lieder."
May 18, 2016
On Tuesday, 17 May 2016 at 16:24:31 UTC, jmh530 wrote:
> On Tuesday, 17 May 2016 at 14:06:37 UTC, Jack Stouffer wrote:
>> http://jackstouffer.com/blog/d_auto_decoding_and_you.html
>>
>> Based on the recent thread in General, I wrote this blog post that's designed to be part beginner tutorial, part objective record of the debate over it, and finally my opinions on the matter.
>
> I probably would have preferred this split up into two parts with one on the tutorial and one on the record of the debate. It seems to focus more on the debate.

That wasn't my intent. I wanted the debate to be a lens into a discussion of the technical merits and demerits of auto decoding. I have reworded some of the article in order to reflect this.

> Maybe you could get add a section that was like "for THIS type of string, do X for performance" with clear explanations of why that is the best way and why other ways will be slower. Then, you can have other sub-sections for "for THAT type of string, do Y for performance." You have some of this detail in there, but it's organized more with respect to the context of the debate, I think.

I will add this, thanks.


May 18, 2016
On Tuesday, May 17, 2016 17:36:44 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)?

At this point, if anyone ever calls front with parens, they're doing it wrong. The range API checks that accessing front as if it were a variable works and _not_ whether calling it as a function works. So, front can be a variable, an enum (though that wouldn't make much sense), a function, or a property function. All of those are legal. And properly written range-based code will work with all of them, because it won't use parens.

The only reason to use parens on front would be if it returned a callable, and since @property doesn't handle that correctly right now (the first set of parens still call the function, not what it returns), it really doesn't work correctly to have a range of callables - at least not and call them without assigning them to a variable first.

> 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?

IIRC save stopped checking for that around dconf of last year, since given that it's perfectly legit to call normal functions without parens, and there is no strong property enforcement, it makes no sense to require that save be a property function. But I don't think that isInputRange ever checked that front or empty were property functions (and if it did, I don't know that it would have worked for them to ever be variables - that would depend on how the check for whether it was a property function was done).

Regardless, anyone who ever calls front or empty with parens is writing bad code that will not work generically, because that's not what the range API dictates. That's one reason why I wish that we had strict property enforcement, but there's no way that we're getting that at this point. So, while we do have enforcement of how ranges _can_ be used, we don't have enforcement of how they _are_ used, and I don't expect that we'll ever get that.

- Jonathan M Davis

May 18, 2016
On Wednesday, 18 May 2016 at 20:10:09 UTC, Jonathan M Davis wrote:
>
> At this point, if anyone ever calls front with parens, they're doing it wrong.

Is this true of all @property functions? Should this be noted in the spec? Should it be an error? If it shouldn't be an error, is it really such a bad thing?
May 19, 2016
On Wednesday, 18 May 2016 at 20:10:09 UTC, Jonathan M Davis wrote:
> At this point, if anyone ever calls front with parens, they're doing it wrong.

$ cd ~/dlang/phobos && grep -r "\.front()" * | wc -l
3

Not bad. One is commented out and the other two look intentional.
May 19, 2016
On Wednesday, 18 May 2016 at 22:23:45 UTC, jmh530 wrote:
> Is this true of all @property functions?

No, this is purely a range thing where it's legal to have your front be a public member variable rather than a getter function.

> Should this be noted in the spec?

While somewhat supported in the language, at the end of the day ranges are library types, so no.

> Should it be an error?

No, people's code will error if they try to call a non callable anyway.