March 21, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch


--- Comment #30 from timon.gehr@gmx.ch 2013-03-21 12:56:04 PDT ---
(In reply to comment #16)
> The idea in comment #11 is interesting, but one problem point is that current compiler does not see UFCS fallback for operator overloading.
> 

Making this work enables transparent introduction of the opDollar requirement for eg. finite RandomAccessRanges.

> If we accept it, should we also accept this?
> 
> string opBinary(string op)(string s1, string s2) if (op == "+") {
>     return s1 ~ s2;
> }
> void main() {
>     assert("hello " + "world!" == "hello world!");
>     // --> "hello ".opBinary!"+"("world!")    // op-overloading
>     // --> .opBinary!"+"("hello ", "world!")  // UFCS
> }

IMO yes. In any case, there is nothing in the spec that would indicate that it does not work.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #31 from timon.gehr@gmx.ch 2013-03-21 13:02:41 PDT ---
(In reply to comment #24)
> (In reply to comment #22)
> > ...
> > the same reason. As it stands, you pretty much can't use $ in generic code.
> > It's only good for arrays, because you can't count on it working for anything
> > else.
> 
> Yes you can, it just requires the range supports $.  Define supportsDollar
> trait.  Done.
> ...

Needing to state in the template constraint that a type supports syntax sugar appears to be sub-optimal at best. (Whether or not it is used will usually be an implementation detail.) IMO adding opDollar using UFCS makes the most sense.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #32 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-03-21 13:15:39 PDT ---
(In reply to comment #31)
> Needing to state in the template constraint that a type supports syntax sugar appears to be sub-optimal at best. (Whether or not it is used will usually be an implementation detail.) IMO adding opDollar using UFCS makes the most sense.

I think the mistake here is the assumption that $ is syntax sugar.  opDollar is a function, and is not required to return length, otherwise we wouldn't be having this discussion.

A more semantically named trait would be hasEnd.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #33 from monarchdodra@gmail.com 2013-03-21 14:14:50 PDT ---
(In reply to comment #29)
> (In reply to comment #28)
> > Yeah, exactly what he said. Having yet another trait means: a) Don't test the trait and ignore opDollar.
> 
> By your own definition (1. we don't check for it, and 2. you can't write generic code with $), that is exactly what is done now.
> 
> > b) Test the trait and fork the code even more.
> 
> Huh?  If your algorithm requires opDollar, use it.  If not, then it didn't exist before.  Where is the forking?
> 
> I looked at isRandomAccessRange.  It can be true if the range is infinite, which most likely do NOT define $.  If that is the case, how can generic code use $ simply if isRandomAccessRange is true?

What's your point? isRandomAccessRange doesn't require length either. Does that mean code that tests isRandomAccessRange can't use length? That's why we usually test RA+hasLength. However, once you have an RA range that defines length, it would make little sense for r[$ - 1] to not function.

Also, *sliceable* infinite ranges most definitely *do* define opDollar, and it is part of the requirements we'd like to add to *isSliceable*. Heck, at one point, it was argued that that should be the *only* requirement (int to $)

This would be breaking change, but sliceable infinite is new concept, so it would break very little. And in this case, it would actually be a functional upgrade.

Take a look at popFrontN's implementation for an example of how this would help tons. I have an open pull for chunks. Making slicing work trying to work around opDollar is a nightmare.

Having the guarantee that r[1 .. $] works means we wouldn't even have to worry about whether or not r is finite. Or if it defines opDollar for that matter.

> > What we are trying to do is:
> > a) Not break code by adding more to the requirements.
> 
> Wait, I thought we are adding opDollar to the requirements?

No. What we want is that if a range is finite and random access, then writing "r[$ - 1]" should be legal. And "r[0 .. $]" should be legal for sliceables (regardless of length).

That is the goal. We are discussing the how. One idea is to change the trait. What we'd want is a functionality that would allow us to do this without breaking existing code.

> > b) Provide an external solution for ranges that don't define opDollar (because
> > for a range, defining opDollar as an alias of length IS natural).
> 
> As I previously stated, I don't have a problem with this, as long as it only applies to ranges you define, and NOT ranges or types where it makes no sense.
> 
> 1. opDollar is NOT equivalent to length in all cases.  Therefore, making it
> equivalent by default BY DEFINITION breaks existing code that purposely defines
> length and purposely omits opDollar.
> 2. Adding opDollar requirements to range traits requires all existing ranges
> that could define opDollar DO define opDollar.
> 3. You wish to avoid immediate breakage of code that has not yet implemented
> opDollar but satisfies current implementation of said traits.

Ranges is a phobos concept we can define ourselves as we so wish. If you decide to adhere to the interface, but do non-sense with it, that becomes _your_ problem. In regards to *ranges*, if one defines length, but not opDollar, then it would make *0* sense for r[0 .. $] to not mean r[0 .. r.length]. If you have a "ranges [...] where it makes no sense", then it is the range that makes no sense.

The range may also decide to implement it's own opDollar if it so wishes. But if it doesn't, we can do it. We do this with UFCS all the time. I don't see why we can't do it for opDollar to, either via a global function, or compiler help.

> So in other words your goal is to break existing code so other existing code doesn't break?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #34 from timon.gehr@gmx.ch 2013-03-21 14:32:09 PDT ---
(In reply to comment #32)
> (In reply to comment #31)
> > Needing to state in the template constraint that a type supports syntax sugar appears to be sub-optimal at best. (Whether or not it is used will usually be an implementation detail.) IMO adding opDollar using UFCS makes the most sense.
> 
> I think the mistake here is the assumption that $ is syntax sugar.  opDollar is a function, and is not required to return length, otherwise we wouldn't be having this discussion.
> 
> A more semantically named trait would be hasEnd.

Ok. Still, a finite RandomAccessRange should always satisfy hasEnd.

opDollar is syntax sugar. I do not think there is a halfway decent API where opDollar is not an alias to a more aptly named member.

For ranges, it is length, for dcollections, it might be end, etc.

If opDollar is not considered syntax sugar, you have:

auto end = m.opDollar();

However, why does it even make sense to make opDollar denote end? There is no analogue for begin.

m[m.begin()..m.end()]
...
m[m.begin()..$]
...
uh.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #35 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-03-21 18:49:56 PDT ---
(In reply to comment #34)
> opDollar is syntax sugar. I do not think there is a halfway decent API where opDollar is not an alias to a more aptly named member.

Maybe true.  But maybe that's only true because opDollar didn't work for a long time.

What about an infinite range where the "end" is not really defined, but you need something to say that the upper bound is unbounded?

would that have a use case besides being used in slicing?

> However, why does it even make sense to make opDollar denote end? There is no analogue for begin.
> 
> m[m.begin()..m.end()]
> ...
> m[m.begin()..$]
> ...

I suggested it, it was shot down.  Walter seems convinced that 0 fills that role despite all attempts to explain.

http://forum.dlang.org/post/op.vco5zwhreav7ka@localhost.localdomain

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #36 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-03-21 19:42:41 PDT ---
(In reply to comment #33)
> What's your point? isRandomAccessRange doesn't require length either. Does that mean code that tests isRandomAccessRange can't use length? That's why we usually test RA+hasLength. However, once you have an RA range that defines length, it would make little sense for r[$ - 1] to not function.

And it probably would function.  You don't need a trait to write code that expects $ to work.  And even if $ DID work, it may not work the way you expect, that is, length and $ may not be equivalent.  In other words, it's impossible to write a trait that says "$ must be equivalent to length."

It is OK with me, however, if you want to say that a RA range with hasLength requires $ to function as length.

I just don't want the compiler to assume that $ means length for all types.

> No. What we want is that if a range is finite and random access, then writing "r[$ - 1]" should be legal. And "r[0 .. $]" should be legal for sliceables (regardless of length).

r[0..$] is equivalent to r[], there is no need to require it.

> That is the goal. We are discussing the how. One idea is to change the trait. What we'd want is a functionality that would allow us to do this without breaking existing code.

Changing the trait will break existing code, making the assumption will break existing code.  There is nothing that can be done I can think of that wouldn't break existing code.

So if you have to break existing code, break phobos code that can be fixed in the same commit!

> Ranges is a phobos concept we can define ourselves as we so wish. If you decide to adhere to the interface, but do non-sense with it, that becomes _your_ problem. In regards to *ranges*, if one defines length, but not opDollar, then it would make *0* sense for r[0 .. $] to not mean r[0 .. r.length]. If you have a "ranges [...] where it makes no sense", then it is the range that makes no sense.

That is fine, as I've already said.  If you want to change the trait, go right ahead!

> The range may also decide to implement it's own opDollar if it so wishes. But if it doesn't, we can do it. We do this with UFCS all the time. I don't see why we can't do it for opDollar to, either via a global function, or compiler help.

Doing it in the compiler is not correct, the compiler shouldn't care what opDollar means.  Otherwise, it should just make $ mean length.  Ranges are a phobos concept.  If you want to define it for isRandomAccessRange + hasLength only, I think that is fair too (I'm assuming here we can change the compiler to allow adding opDollar using UFCS).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #37 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-03-21 21:27:07 PDT ---
I think that having opDollar work with UFCS would set a bad precedent. That's opening the door for 3rd party code to be able to overload operators on your types, and I think that that's a pretty bad can of worms to open.

On the whole, I don't see a problem with length being aliased to opDollar if opDollar isn't defined except for the case where you _don't_ want opDollar to be defined, and I don't know if requiring that opDollar be explicitly disabled in that case is a good idea or not.

If we don't implement this enhancement request though, I'm very much inclined to put a note in the changelog (probably in red) which warns people that hasSlicing will soon be requiring opDollar as will isRandomAccessRange for finite ranges, so people should update their code to have opDollar (even if it's just an alias to length) so that it doesn't break when we make the changes in hasSlicing and isRandomAccess range in a release or two. That's not ideal, but it would at least give people a chance to avoid the code breakage if they're proactive.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #38 from Kenji Hara <k.hara.pg@gmail.com> 2013-03-21 22:15:44 PDT ---
For the discussion, I created experimental patch for dmd and Phobos.

https://github.com/9rnsr/dmd/branches/fix7177alt https://github.com/9rnsr/phobos/branches/fix7177alt

Automatic opDollar completion by std.range would work well.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177



--- Comment #39 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-03-22 08:33:31 PDT ---
(In reply to comment #37)
> I think that having opDollar work with UFCS would set a bad precedent. That's opening the door for 3rd party code to be able to overload operators on your types, and I think that that's a pretty bad can of worms to open.

This can already be done with a wrapping type and alias this.  See my earlier example.

However, we can probably make opDollar a special case, it's not really an operator but a special symbol that $ gets translated into.  I don't think it would be inconsistent to allow UFCS opDollar and not allow other operators via UFCS.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------