www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - alias this and array popFront: is this a bug?

reply "monarch_dodra" <monarchdodra gmail.com> writes:
//----
struct S
{
    int[] r;
    alias r this;
}

void main()
{
    S s;
    s.front(); //OK
    s.popFront(); //No Match
    static assert (isForwardRange!S); //Nope
}
//----

The problem, basically, is that front's signature is (basically):
 property ref T front(T)(T[] a)
     if (isDynamicArray!(T[]))

popFront's signature though is:
void popFront(A)(A a)
     if (isDynamicArray!A)

The problem is that the constraint "isDynamicArray" requires an 
exact match. This means in the case of front, S is converted via 
alias this to int[], and the constraints pass. In the case of 
popFront, however, S is taken directly as is, and the test 
isDynamicArray fails.

I tried changing the signature to popFront, and everything works 
fine all over phobos. (except for a twisted unittest that tested 
popFront specifying the template parameters, but doing that 
sounds like nonsense to me, and is just badly written test).

Does anybody know if there is a reason other than "historical" 
for this?

I find it stange that front and popFront have different 
behaviors, so I think one of either should be "fixed".

IMO, I think accepting the S type makes sense. Thoughts?
Mar 12 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
monarch_dodra:

 IMO, I think accepting the S type makes sense. Thoughts?
Seems meaningful to accept S. But the last word on ranges is of Andrei :-) Bye, bearophile
Mar 12 2013
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 12 Mar 2013 07:28:29 -0400, monarch_dodra <monarchdodra gmail.com>  
wrote:


 IMO, I think accepting the S type makes sense. Thoughts?
I think you should file an enhancement request. It sounds reasonable. -Steve
Mar 12 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, March 12, 2013 12:28:29 monarch_dodra wrote:
 IMO, I think accepting the S type makes sense. Thoughts?
Honestly, I find implicit conversion on template constraints to be very dangerous, because it's so insanely easy to get something that passes the constraint but doesn't actually work with the code (which is a big reason that isDynamicArray only works on the exact type). So, I'm not really a fan of the idea of the alias this working like you're trying to do. But the fact that it's inconsistent definitely isn't good. It should either work with both front and popFront or reject both. - Jonathan M Davis
Mar 12 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 12 March 2013 at 14:44:04 UTC, Jonathan M Davis wrote:
 On Tuesday, March 12, 2013 12:28:29 monarch_dodra wrote:
 IMO, I think accepting the S type makes sense. Thoughts?
Honestly, I find implicit conversion on template constraints to be very dangerous, because it's so insanely easy to get something that passes the constraint but doesn't actually work with the code (which is a big reason that isDynamicArray only works on the exact type).
I agree, things like "isXXX" should answer true iff said thing IS an XXX, not merelly "is convertible to". On the other hand, with proper template semi-specialization, you can get the arguments converted at the call site, meaning that inside the implementation, the constraints are passed fair and square.
 So, I'm not really a fan of the
 idea of the alias this working like you're trying to do. But 
 the fact that
 it's inconsistent definitely isn't good. It should either work 
 with both front
 and popFront or reject both.

 - Jonathan M Davis
I definitely agree on the "both" point. However, given the "philosophy" of "alias this", if a function accepts a T, it should be "callable" with an object that defines "alias T this" (note I said callable, not accepts... nuance). So I'd be inclined to use the "void popFront(T)(ref T[] a)" version. I'll try to spend the next couple of days to see try to find if a case that would break with this scheme.
Mar 12 2013