digitalmars.D.bugs - [Issue 7177] New: $ should forward to length by default
- d-bugmail puremagic.com (21/21) Dec 28 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (17/17) Dec 28 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (17/17) Dec 29 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (8/8) Dec 29 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (17/20) Dec 29 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (14/15) Dec 29 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (15/33) Dec 29 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (15/15) Oct 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (12/12) Dec 17 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (6/6) Feb 06 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/10) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (54/55) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (19/19) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (16/25) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (35/41) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (9/15) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (16/16) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (24/31) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (11/13) Mar 21 2013 That's not a problem at all. As long as the logic is that length is alia...
- d-bugmail puremagic.com (12/26) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (25/39) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (11/13) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (12/14) Mar 21 2013 Because if you don't, then you can never use $ when slicing a range. And
- d-bugmail puremagic.com (13/13) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (18/26) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (11/11) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (16/20) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/11) Mar 21 2013 Because it makes yet another thing that range-based functions must test ...
- d-bugmail puremagic.com (22/29) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (25/32) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (14/27) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (9/18) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/13) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (36/70) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (19/29) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (14/23) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (26/45) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (20/20) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (9/9) Mar 21 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (12/15) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (29/34) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (16/29) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/39) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (13/13) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (28/28) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (7/7) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (14/15) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/21) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (13/33) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/17) Mar 24 2013 Yes.
- d-bugmail puremagic.com (29/30) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (8/10) Mar 24 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (16/39) Mar 25 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (40/40) Mar 26 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (33/33) Mar 27 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (20/52) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (19/33) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (30/45) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (28/53) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (30/81) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (12/15) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (7/12) Apr 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (8/16) Apr 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (19/31) Apr 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (8/12) Apr 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (25/43) Apr 02 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (10/23) Apr 02 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (9/31) Apr 02 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (8/14) Apr 02 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (27/33) Apr 02 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
- d-bugmail puremagic.com (7/7) Apr 03 2013 http://d.puremagic.com/issues/show_bug.cgi?id=7177
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Summary: $ should forward to length by default Product: D Version: D2 Platform: Other OS/Version: Linux Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: dsimcha yahoo.com See the following pull request: https://github.com/D-Programming-Language/phobos/pull/365 Andrei and I agree that this kind of boilerplate is unacceptable. To get the benefits of opDollar without it, there needs to be some default behavior that forwards to .length if no explicit opDollar exists. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 28 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug yahoo.com.au The effect of this would be that people would declare 'length' instead of 'opDollar' in nearly all cases. This would mean that you declare opDollar if and only if you want $ without defining 'length'. (or if $ should be different to length). Is this what we want? Is there anything in the existing language which behaves in this way? Or would this be introducing an unprecedented funky behaviour? (Just want to think through the implications, I'm not intrinsically opposed to the idea). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 28 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Andrei Alexandrescu <andrei metalanguage.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrei metalanguage.com 12:30:22 PST --- I'm unclear what the best approach this is. One guiding element is that https://github.com/D-Programming-Language/phobos/pull/365 is pure boilerplate, which goes quite against the grain of D. It's also something that affects a lot of ranges (essentially all that define a length). The way I see it, we should automate things such that 1-dimensional ranges that have a notion of "length" should define length (and opDollar should automatically work for them), and multi-dimensional ranges with more refined needs would define opDollar and also length. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 29 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 12:31:58 PST --- Let me add that it's not impossible there are ranges that do have multi-dimensional slicing but possibly no notion of "length". Sparse matrices come to mind. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 29 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177Let me add that it's not impossible there are ranges that do have multi-dimensional slicing but possibly no notion of "length". Sparse matrices come to mind.Yes. Another difference is that length is generally an integer. opDollar doesn't need to be, it could be any object. It can also be cheap to calculate opDollar but expensive to determine length. I guess the question is, for what fraction of use cases will opDollar and length coincide? It seems to be true for most ranges, which is interesting because they didn't even exist when this feature was first implemented -- it was designed for matrices -- yet they're now shaping us an important use of it. I don't think that there will be much application code that uses multi-dimensional opDollar, so it doesn't matter so much if those cases have a fair bit of boilerplate. How commonly will people declare new ranges in application code? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 29 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bearophile_hugs eml.cc At first sight I like this proposal.How commonly will people declare new ranges in application code?iterators quite often (using the yield keyword, and in Python using lazy list comps too), but in D they are much less handy to write. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 29 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 15:50:54 PST ---Given a value x of type T, if the user is able to write both x.length and x[0 .. $] then it should be reasonable to expect the latter is interchangeable with x[0 .. x.length].Let me add that it's not impossible there are ranges that do have multi-dimensional slicing but possibly no notion of "length". Sparse matrices come to mind.Yes. Another difference is that length is generally an integer. opDollar doesn't need to be, it could be any object. It can also be cheap to calculate opDollar but expensive to determine length. I guess the question is, for what fraction of use cases will opDollar and length coincide?It seems to be true for most ranges, which is interesting because they didn't even exist when this feature was first implemented -- it was designed for matrices -- yet they're now shaping us an important use of it. I don't think that there will be much application code that uses multi-dimensional opDollar, so it doesn't matter so much if those cases have a fair bit of boilerplate. How commonly will people declare new ranges in application code?Hard to estimate, but I suspect a fair amount (and we want to encourage that). In STL defining an iterator is an act of courage, but we'd ideally hope that people can easily define ranges that integrate with a variety of algorithms. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 29 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmx.com PDT --- It would be great to be able to rely on $ working with slicing with any range type, but right now, that would require that all sliceable ranges overload opDollar, which obviously isn't the case right now and is arguably unreasonable to expect (especially given the boilerplate involved). So, if we're going to require that $ work with slicing (which we really should do), then this proposal is pretty much required. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Commit pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/a0b82a53b89c69102a0ab0c2e16cbb013550c723 Add some requirements for opDollar to hasSlicing. Ideally, opDollar would be outright required for any range with slicing, but unless/until it's changed so that length automatically aliases to a reasonable requirement to make. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 17 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7177 19:53:03 PST --- *** Issue 2635 has been marked as a duplicate of this issue. *** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 06 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Kenji Hara <k.hara.pg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull --- https://github.com/D-Programming-Language/dmd/pull/1779 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 monarchdodra gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra gmail.comhttps://github.com/D-Programming-Language/dmd/pull/1779I'm a bit on the fence about this. I don't think it's the compiler's job to translate $ into length. length is not a magic word, it is just a range primitive. The compiler should have no knowledge about either of these. Further more, I think it could be dangerous to forward $ to length for any indiscriminate type. Couldn't we implement this instead as a library solution, inside std.range? For example, std.array provides (pop)[front|back] for arrays. This is library, not compiler. We could have std.range provide an global opDollar function that returns it's range argument's length instead? Simply: //-------- import std.stdio; import std.range; auto opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } struct S { property { enum empty = false; int front(){return 1;} size_t length(){return 10;} } void popFront(){} int opIndex(size_t i){return i;} } void main() { S s; writeln(s[$]); } //-------- Idea being that if you call: R r; r[$ - 1]; Then: Either R defines opDollar, and everyone is happy. If not, and if range is imported, the the compiler "sees" an available std.range.opDollar function, and uses that instead. That doesn't work right now (it just says "undefined identifier __dollar"), so it would still require a bit of compiler improvement, but I think it would be a better direction to take. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT --- If you have a type which defines length and has slicing or indexing, does it make any sense whatsoever for length _not_ to be the same as opDollar? I'd strongly argue that any type (be it a range or otherwise) which had indexing or slicing and had length and made opDollar something else other than length (or length something else than one past the last index) would be very badly designed. If we don't make it so that length automatically aliases to opDollar if opDollar isn't already defined, then almost every single finite random-access range ever will have to manually alias length to opDollar, and we'll never be able to require that ranges with slicing define opDollar, because it would break too much code if we did. I see no downside to this and huge problems if we don't do this. This is the key to being able to rely on opDollar existing for ranges types that should define it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177If we don't make it so that length automatically aliases to opDollar if opDollar isn't already defined, then almost every single finite random-access range ever will have to manually alias length to opDollar, and we'll never be able to require that ranges with slicing define opDollar, because it would break too much code if we did. I see no downside to this and huge problems if we don't do this. This is the key to being able to rely on opDollar existing for ranges types that should define it.They point of dissension here (as I see it), is that you are saying that a range must define opDollar one way or another, whereas I think all we need is for r[$ - 1]/r[0 .. $] to work. My proposal would not prevent isSliceable for checking this, any less than isInputRange says that slices are ranges. Slices have front defined externally, which allows us to use them as ranges all over the place. I don't see why we can't use the same approach with ranges and opDollar. I agree it is a HUGE boost to be able to rely on "r[0 .. $]" being legal. I just find it is kind of iffy to rely on the compiler for that... But just to be clear, I prefer this than no solution. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 07:30:56 PDT ---If you have a type which defines length and has slicing or indexing, does it make any sense whatsoever for length _not_ to be the same as opDollar? I'd strongly argue that any type (be it a range or otherwise) which had indexing or slicing and had length and made opDollar something else other than length (or length something else than one past the last index) would be very badly designed.Yes, it makes sense in some cases for opDollar not to be length. In the case of dcollections, I want opDollar to map to .end() (which is the last cursor), not .length. Please don't make $ map to .length, it will break current dcollections. Example: I allow slicing based on index for TreeMap, because indexes are in order. This code, would potentially compile, but return the unexpected slice of half the elements in the TreeMap: auto m = new TreeMap!(int, int); m[0] = 0; m[2] = 2; m[4] = 4; m[6] = 6; assert(m.length == 4); auto sl = m[0..$]; // translates to m[0..m.length]; assert(sl.walkLength() == 2); // only 2 elements! What I would like is for $ to map to m.end(). Another example is int[int]: int[int] x; x[1] = 14; x[100] = 42; assert(x[$-1] == 14); if $ maps to x.length, then it happens to coincide with x[1], but that isn't necessarily the "last" element in the AA (which is how it reads). In fact, I would argue x[$-1] shouldn't compile, it's value is meaningless. Sorry that it makes you have to add boilerplate, but I think it's incorrect to always equate length with $. The boilerplate isn't actually that bad, it's just an alias. In generated code it adds NO bloat. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---Another example is int[int]: int[int] x; x[1] = 14; x[100] = 42; assert(x[$-1] == 14);That's a strong case. If compiler tries to translate $ to length automatically, library AA implementation will become impossible. I'll close my pull request. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 --- compiler does not see UFCS fallback for operator overloading. 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 } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com 08:24:32 PDT ---compiler does not see UFCS fallback for operator overloading.That is a deficiency that is easily worked around: struct Concatable { private string str; this(string str) {this.str = str;} string opBinary(string op)(string other) if (op == "+") {return str ~ other;} } Concatable c(string s) { return Concatable(s);} auto s = "hello".c + "world";If we accept it, should we also accept this? string opBinary(string op)(string s1, string s2) if (op == "+") { return s1 ~ s2; }Should we accept that this is now possible? Sure, I don't see why not, it is quite possible without additions to the language to make that a reality with a tiny insignificant annoyance. Should we accept string + string as a feature of D/phobos? No. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT ---That's a strong case. If compiler tries to translate $ to length automatically, library AA implementation will become impossible.That's not a problem at all. As long as the logic is that length is aliased to opDollar as long as opDollar isn't defined, then it won't break anything. Anything that needs to define opDollar differently will define opDollar, and for the rest, if they define length, then it gets aliased to opDollar. I really don't see the problem with that. And without this, requiring opDollar with hasSlicing will break tons of code. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Yes, it makes sense in some cases for opDollar not to be length. [SNIP]Note though that opDollar would *fallback* to length if you did not implement opDollar. You are still free to implement your own opDollar if you wish, so your DCollections would still be fine.No need! Please don't close it quite yet. A simple " disable opDollar();" or "private opDollar();" should shut down this problem. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Another example is int[int]: int[int] x; x[1] = 14; x[100] = 42; assert(x[$-1] == 14);That's a strong case. If compiler tries to translate $ to length automatically, library AA implementation will become impossible. I'll close my pull request.
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 09:11:43 PDT ---The point of the AA example is that opDollar should be illegal, not that it should map to something else. I don't think we need to require opDollar with hasSlicing, why would you think that?That's a strong case. If compiler tries to translate $ to length automatically, library AA implementation will become impossible.That's not a problem at all. As long as the logic is that length is aliased to opDollar as long as opDollar isn't defined, then it won't break anything. Anything that needs to define opDollar differently will define opDollar, and for the rest, if they define length, then it gets aliased to opDollar. I really don't see the problem with that. And without this, requiring opDollar with hasSlicing will break tons of code.Note though that opDollar would *fallback* to length if you did not implement opDollar. You are still free to implement your own opDollar if you wish, so your DCollections would still be fine.My point is that I have to opt out of that behavior. This means it breaks my current code.No need! Please don't close it quite yet. A simple " disable opDollar();" or "private opDollar();" should shut down this problem.This is a good thing to bring up, but I don't really understand why opDollar needs to be implemented by default. It's only valid inside indexers, and only makes sense for indexes that are integers, begin at 0, and end at .length. Isn't that a lot of assumptions to make for opIndex, which can take any type of argument, and whose domain space can mean anything? We can prove that a type has indexing, that it has length, even possibly that it's indexer takes the same type as length returns, but I think it's too assuming to guess at the domain space of the index. Why is it so bad to explicitly alias opDollar to length? It seems we are using anecdotal evidence (phobos requires a few aliases) to apply to all code in existence and that ever will exist. An alias consumes NO code space, it's free. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 09:16:14 PDT ---My point is that I have to opt out of that behavior. This means it breaks my current code.To expand on this point, I would say implementing opDollar by default to mean .length should be semantically correct in all existing code that defines indexing and length. If not (and I think I've shown that it's not always correct), it should not be done. It breaks too much existing code otherwise. The gain is so little since aliasing already works. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT ---I don't think we need to require opDollar with hasSlicing, why would you think that?Because if you don't, then you can never use $ when slicing a range. And really, isRandomAccessRange should require that $ work with finite ranges for 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. The appropriate range templates must be able to require them for us to be able to use them, and if we change them to require opDollar without this enhancement request, then it's going to break a lot of code. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT --- If we forgo this enhancement request, then we have two choices with regards to ranges and $: 1. Never be able to use $ with ranges, because none of the range traits check for it. 2. Warn people that we're going to soon require opDollar for random-access ranges and ranges with slicing and then change isRandomAccessRange and hasSlicing accordingly (at which point, there's bound to be a fair bit of code which will break). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 10:14:53 PDT ---Because if you don't, then you can never use $ when slicing a range.This is extreme. You certainly CAN use $ with ranges that support $.And really, isRandomAccessRange should require that $ work with finite ranges for 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.The appropriate range templates must be able to require them for us to be able to use them, and if we change them to require opDollar without this enhancement request, then it's going to break a lot of code.Then don't change them. Requiring $ is as simple as defining a trait that checks for $ support. There is no reason slicing has to be predicated on having an end point. And having an end point does not require having a length (see strings) and is not necessarily an integer value equivalent to the length. If, for example, we add requiring $ for isRandomAccessRange, and then have a function that requires a random access range but doesn't use $, what is the benefit of doing that? Either you need $ or you don't, and that is quantifiable with a separate trait. Support for slicing or indexing is a precondition for having $ but $ is not required in order to slice or index. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT --- I really don't think that it makes sense to define ranges with slicing which don't have opDollar or finite random-access ranges which don't have opDollar. And having hasOpDollar or supportsOpDollar just complicates ranges even further. I expect that the main reason that opDollar wasn't required in the first place was that it didn't even work until recently (though it may also have simply been forgotten). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 10:47:03 PDT ---I really don't think that it makes sense to define ranges with slicing which don't have opDollar or finite random-access ranges which don't have opDollar.Then why is this necessary? If it only makes sense to define opDollar, then it will be defined, and you can use it.And having hasOpDollar or supportsOpDollar just complicates ranges even further.What? How does it do anything to make ranges more complex? If anything, adding it to isRandomAccessRange makes them more complex, because now ranges that previously satisfied that trait may now not satisfy it. Defining a new trait does not make anything more complex, nothing is required to implement a new trait, because nothing currently uses that trait. No more changes are required to satisfy a new hasOpDollar trait than are required to satisfy an isRandomAccessRange trait that now requires opDollar. In fact the same code is required. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT ---How does it do anything to make ranges more complex?Because it makes yet another thing that range-based functions must test for. We arguably have too many such traits already. The _only_ reason I see to not require that opDollar work with ranges which have slicing and finite random-access ranges is the fact that the change will break code. IMHO, everything else about it is exactly the right thing to do. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Yeah, exactly what he said. Having yet another trait means: a) Don't test the trait and ignore opDollar. b) Test the trait and fork the code even more. Neither is satisfactory. Requiring RA and slicing to support $ is just what makes sense and is natural. Making it "yet another trait" would be wrong. Just... wrong. What we are trying to do is: a) Not break code by adding more to the requirements. 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). And as long as we don't have this, $ is just as good as useless in generic code. The only place I know of where we use it is for popFrontN, and even then we jump through hoops to get it to work. Getting this ER to work, in one way or another, is very important for the natural and generic usage of ranges. Right around now, I'm kind of wishing I had kept my mouth shut, because I too have been waiting for this for a while :/ -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------How does it do anything to make ranges more complex?Because it makes yet another thing that range-based functions must test for. We arguably have too many such traits already. The _only_ reason I see to not require that opDollar work with ranges which have slicing and finite random-access ranges is the fact that the change will break code. IMHO, everything else about it is exactly the right thing to do.
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 12:47:14 PDT ---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 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?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. 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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 timon.gehr gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr gmx.chcompiler 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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Needing 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: -------... 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. ...
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 13:15:39 PDT ---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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177What'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.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?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.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?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.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.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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Ok. 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: -------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.
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 18:49:56 PDT ---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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 19:42:41 PDT ---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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 --- 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: -------
Mar 21 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 08:33:31 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.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: -------
Mar 22 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177However, we can probably make opDollar a special case, it's not really an operator but a special symbol that $ gets translated into.By that logic, opBinary is not really an operator, but a special symbol "+" gets translated into. Besides, you could do very stupid stuff with opDollar the same as with any operator. //Convenience to transform a pointer into a slice: size_t opDollar(T)(T* p) { return 1; } ... void main() { int i = 1; int* p = &i; int[] s = p[0 .. $]; //Now legal! } So allowing opDollar as non-member operator could be used unsafely just the same as any other operator.I don't think it would be inconsistent to allow UFCS opDollar and not allow other operators via UFCS.I'm really just questioning why we don't allow UFCS for *all* operators? Seems like a restriction when you take into account the fact that you have UFCS. After all, it can already be used to give built-in types new attributes. Why are operators different from functions? There will always be stupid users to do stupid things with code. I don't see why it should prevent us from having useful and smart tools. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 22 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 09:23:48 PDT ---It's most definitely not an operator, despite the name. It's a property. To say opDollar is an operator is like saying length is an operator.However, we can probably make opDollar a special case, it's not really an operator but a special symbol that $ gets translated into.By that logic, opBinary is not really an operator, but a special symbol "+" gets translated into. Besides, you could do very stupid stuff with opDollar the same as with any operator.So allowing opDollar as non-member operator could be used unsafely just the same as any other operator.You misunderstand, what I meant was because it's not technically an operator, we could give it special permission to allow UFCS and technically be correct saying we don't allow operator overloading with UFCS. I didn't say it would always be safe!I'm really just questioning why we don't allow UFCS for *all* operators? Seems like a restriction when you take into account the fact that you have UFCS. After all, it can already be used to give built-in types new attributes. Why are operators different from functions?I don't have a problem with it, I was suggesting we could allow it only for opDollar as a compromise for those who feel operators shouldn't be UFCS-able. In fact, we already can add operators via type-wrapping and alias this. I don't see the issue with allowing UFCS as a cleaner solution for that. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 22 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177You play on words. Both are not exclusive. It is an operator that is a property. BTW, is opUnary++ as operator? opUnary! ? In any case, I see no point in arguing over this particular point.It's most definitely not an operator, despite the name. It's a property. To say opDollar is an operator is like saying length is an operator.However, we can probably make opDollar a special case, it's not really an operator but a special symbol that $ gets translated into.By that logic, opBinary is not really an operator, but a special symbol "+" gets translated into. Besides, you could do very stupid stuff with opDollar the same as with any operator.I think we are on the same page. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------So allowing opDollar as non-member operator could be used unsafely just the same as any other operator.You misunderstand, what I meant was because it's not technically an operator, we could give it special permission to allow UFCS and technically be correct saying we don't allow operator overloading with UFCS. I didn't say it would always be safe!I'm really just questioning why we don't allow UFCS for *all* operators? Seems like a restriction when you take into account the fact that you have UFCS. After all, it can already be used to give built-in types new attributes. Why are operators different from functions?I don't have a problem with it, I was suggesting we could allow it only for opDollar as a compromise for those who feel operators shouldn't be UFCS-able. In fact, we already can add operators via type-wrapping and alias this. I don't see the issue with allowing UFCS as a cleaner solution for that.
Mar 22 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT --- I think that being able to do something like overload + for strings would be very bad (which having UFCS work with overloaded operators would allow), and the fact that there would be no way to differentiate between functions when overloaded operators which used UFCS conflicted just makes it worse. But opDollar is quite different from other operators (it's really not any different from overloading any function with a particular name, since it's quite restricted it what it's used for), so maybe it's okay for it. I'd be quite opposed to allowing it in general though. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 22 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 08:24:46 PDT --- I gave this long thread a read and reached a decision. Sorry for the dictatorial approach but this seems to be a matter in which reasonable people may disagree so at some point we need to just choose a way and stick with it. Among my priorities in choosing a behavior is that of simplicity - we can't require people to mind a trait such as supportsOpDollar, or require them to define an alias for opDollar in casual ranges. So, there are a few cases to look at. Given a type T: 1. hasLength!T || isNarrowString!T, but T does not define a member opDollar. Then ALL uses of expr.$ in indexing expressions involving values of type T will automatically alias themselves to expr.length. This includes UFCS, i.e. if user code defines a module-level property length(T), then expr.$ lowers into expr.length which in turn may lower to length(expr). (Note that hasLength!T currently does work with UFCS.) 2. T defines opDollar. Great - nothing to do, it's all explicit. 3. expr.length has no meaning and T does not define opDollar. In this case there is a compile-time error. =========== Regarding having opDollar and/or other operators work as UCSF, this would be desirable from a completeness/expectability/consistency standpoint. I don't quite buy the argument that that opens a can of worms. However, seeing as there's already a compiler change for that, I suggest we go this least-committal route for now and defer that decision for later. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 08:26:27 PDT --- s/UCSF/UFCS/ University of California San Francisco for the win! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 12:55:40 PDT ---1. hasLength!T || isNarrowString!T, but T does not define a member opDollar.this can be shortened to hasLength!T, all strings define $, they are arrays. The compiler shouldn't be trying to guess whether something is a narrow string or not according to phobos (or maybe I read this too literally?) The rest of this is not unreasonable, and aside from breaking current code (albeit less common current code in a non-obvious way), this proposal misses one situation: you want to define .length, but NOT opDollar. In this case, disable opDollar should be allowed (if it's not already) as monarchdodra suggested. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 13:08:46 PDT ---Good point, thanks.1. hasLength!T || isNarrowString!T, but T does not define a member opDollar.this can be shortened to hasLength!T, all strings define $, they are arrays. The compiler shouldn't be trying to guess whether something is a narrow string or not according to phobos (or maybe I read this too literally?)The rest of this is not unreasonable, and aside from breaking current code (albeit less common current code in a non-obvious way), this proposal misses one situation: you want to define .length, but NOT opDollar. In this case, disable opDollar should be allowed (if it's not already) as monarchdodra suggested.Yah, I was thinking of private or disable'd symbols as "defined". Good to clarify that. Kenji, shall we go for this? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177I apologize, but this isn't clear to me. I understand the what/why of the goal, but I don't understand the how? Is it the compiler that is translating $ to length? Then if so, how does "hasLength!T" come into play? Or are we doing this "via" the compiler as a workaround until we can implement opDollar as non-member? (since you mentioned the possibility of allowing non-member operators) I'm sorry, I just want to fully understand which direction we are taking. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Good point, thanks.1. hasLength!T || isNarrowString!T, but T does not define a member opDollar.this can be shortened to hasLength!T, all strings define $, they are arrays. The compiler shouldn't be trying to guess whether something is a narrow string or not according to phobos (or maybe I read this too literally?)The rest of this is not unreasonable, and aside from breaking current code (albeit less common current code in a non-obvious way), this proposal misses one situation: you want to define .length, but NOT opDollar. In this case, disable opDollar should be allowed (if it's not already) as monarchdodra suggested.Yah, I was thinking of private or disable'd symbols as "defined". Good to clarify that. Kenji, shall we go for this?
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 14:51:44 PDT ---I apologize, but this isn't clear to me. I understand the what/why of the goal, but I don't understand the how? Is it the compiler that is translating $ to length?Yes.Then if so, how does "hasLength!T" come into play?Whenever I wrote "hasLength!T" I meant "The expression (expr).length exists for expr of type T".Or are we doing this "via" the compiler as a workaround until we can implement opDollar as non-member? (since you mentioned the possibility of allowing non-member operators)I'm thinking of putting this decision in the compiler for now, it's the least committal change. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---Kenji, shall we go for this?I always think that is not good to enforce particular semantics to the user programs. This enhancement violates the rule, and we already have an example that we should not do it (AA and containers like that). (I know we already have special treatement for ranges - foreach can recognize the object with input range primitives is iterable. But this enhancement just only works for random access range. It is too specialized.) And I found that this is not sufficient - it does not work for infinite forward range! https://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1379 struct IFR // infinite forward range { enum empty = false; property front() { return 1; } auto popFront() {} property save() { return this; } auto opSlice(size_t b, size_t e) { return this.take(e - b); } auto opSlice(size_t b, Infinity) { return this; } } IFR does not have 'length' primitive, but should be slicable like r[n .. $]; (see std.range.hasSlicing definition) But this enhancement cannot cover this - therefore user defined IFR should always define their own opDollar. So, I think the combination of std.range.opDollar and UFCS would be much better than compiler's implicit alias just only for 'length' primitive. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---I'm thinking of putting this decision in the compiler for now, it's the least committal change.To make my suggestion "committal change", I posted it as a pull request. https://github.com/D-Programming-Language/dmd/pull/1793 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 24 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177And I found that this is not sufficient - it does not work for infinite forward range! https://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1379 struct IFR // infinite forward range { enum empty = false; property front() { return 1; } auto popFront() {} property save() { return this; } auto opSlice(size_t b, size_t e) { return this.take(e - b); } auto opSlice(size_t b, Infinity) { return this; } } IFR does not have 'length' primitive, but should be slicable like r[n .. $]; (see std.range.hasSlicing definition) But this enhancement cannot cover this - therefore user defined IFR should always define their own opDollar. So, I think the combination of std.range.opDollar and UFCS would be much better than compiler's implicit alias just only for 'length' primitive.Well, I think the compiler can't do *everything* for the user. If you want an infinite range to adhere to "hasSlicing", then at the very least, it has to implement the slicing primitive. The notion of "slice-able infinite range" has always been ambiguous, but IMO, "slice to end" primitive is the important one that *must* be implemented and checked. I'd doubt we'd break much code enforcing this. Besides, at worst, ranges that can't be sliced to end would seize being considered sliceable, which, IMO, is a good thing anyways. I think we should make this change (for which there would be no automatic workaround) sooner rather than later. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 25 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 PDT --- Implementing it in the language has the advantage of avoiding making it so that opDollar works with UFCS and avoids the risk of someone overloading opDollar in another module and causing stuff to break when it clashes with the one in std.range. It has the disadvantage of not working for infinite ranges while also making $ mean length in cases when we don't want it to, forcing us to disable it. Implementing it in the library has the advantage of making it only work with ranges (unless another overload of opDollar is created for non-ranges) and making it so that it works with infinite ranges. But it has the disadvantage of allowing opDollar to be used with UFCS and risks conflicts if other code also overloads it that way. However, even if we go with the library route, opSlice will still have to explicitly support the type that opDollar returns, so it can't really be supported automatically for infinite ranges. We just save them the trouble of actually aliasing the type to opDollar and make it so that there's a standard type to use with infinite ranges and opDollar (which we could already do by simply declaring something like std.range.InfiniteDollar with the idea that all infinite ranges with slicing would alias it to opDollar and use it with opSlice). So, I don't think that it really matters which way we go as far as infinite ranges go. In either case, some work is required to support it, and requiring opDollar on infinite ranges with slicing will break code (though likely not a lot, since infinite ranges are likely to be a lot rarer than finite ones, and sliceable ones even more so). I think that it mainly comes down to whether we'd rather require that types with length in addition to opIndex and/or opSlice disable opDollar if they don't want it, or whether we'd rather risk 3rd party code defining opDollar as a free function, causing conflicts with std.range.opDollar (conflicts which wouldn't be resolvable in the normal fashion, because $ is an operator, and you can use an import path with it without explicitly calling opDollar). Beyond that, I don't think that it matters much which route we take (though I do worry somewhat that making opDollar UFCS-able would open the door to making other operators UFCS-able, which I think would be a big mistake; but we wouldn't actually be required to do that if we made opDollar UFCS-able), as beyond that, the two routes seem pretty much functionally equivalent. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 26 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 I think I agree that implementing it in the language is a better choice. For one, it means $ will *always* work, as opposed to having to import std.range just to expect generic code to work. As long as it's properly documented, I don't really view the length => $ conversion problematic. Yes, it allows illegal code to compile, but doesn't break anything existing (except for strange static ifs?), and we would be giving users a way to prevent it. I don't view that it wouldn't work "out of the box" with infinite ranges as problematic. There is really no way around the fact that for an infinite range to support "slice to end", it must implement it via a "DollarToken" approach, which pretty much means the code *has* to be deployed. So there is no way to "accidently" forget opDollar. -------- That said, if we do go ahead and implement this, I STRONGLY urge we enforce "hasSlicing" => "can slice to end", even for infinite ranges. Having used infinite ranges in phobos, I can say that: 1. A *LOT* of the slicing that occurs is very often of the form r[i .. $]. 2. A *LOT* of algorithms in phobos would naturally support sliceable infinite ranges with no extra code, if they could rely on being able to write r[i .. $]. Being able *reliably* slice *finite* ranges with opDollar is only half of what we need. I don't think this would break a lot of code as: 1. We are modifying a *trait*, so code that slices would not actually be broken 2. Most of *our* algorithms have fall-backs should a range seize to be sliceable. 3. There are very little infinite ranges anyways jmdavis: Would you be willing to go forward with such a change? You said "I'm very much inclined to put a note in the changelog (probably in red) [...]" would you be inclined to do such a note for only infinite ranges? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 27 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 09:41:17 PDT ---Kenji: I'm a bit unclear on your view on this. You mention you'd prefer a library solution but your pull request seems to go for a in-compiler solution.Kenji, shall we go for this?I always think that is not good to enforce particular semantics to the user programs. This enhancement violates the rule, and we already have an example that we should not do it (AA and containers like that). (I know we already have special treatement for ranges - foreach can recognize the object with input range primitives is iterable. But this enhancement just only works for random access range. It is too specialized.)And I found that this is not sufficient - it does not work for infinite forward range! https://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1379 struct IFR // infinite forward range { enum empty = false; property front() { return 1; } auto popFront() {} property save() { return this; } auto opSlice(size_t b, size_t e) { return this.take(e - b); } auto opSlice(size_t b, Infinity) { return this; } } IFR does not have 'length' primitive, but should be slicable like r[n .. $]; (see std.range.hasSlicing definition) But this enhancement cannot cover this - therefore user defined IFR should always define their own opDollar.There is no intent to cover infinite forward ranges with default behavior. Again, the primary goal here should be, I think, to make code defining casual ranges easy and boilerplate-free. Infinite ranges or ranges that don't define length yet want to define slicing through to the end are comparatively rare. It is reasonable to request people defining those to define opDollar appropriately.So, I think the combination of std.range.opDollar and UFCS would be much better than compiler's implicit alias just only for 'length' primitive.If we go for a library solution, we should define opDollar in object.d so it's available by default. It should look something like this (in the 1-dimensional case): auto ref opDollar(R)(auto ref R r) if (is(typeof(r.length))) { return r.length; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---Kenji: I'm a bit unclear on your view on this. You mention you'd prefer a library solution but your pull request seems to go for a in-compiler solution.'length' would break user-defined containers. The fact clearly represents that we cannot always regard $ as "length". Indeed, it is true in built-in arrays and range concept, but isn't true in associative arrays and some user-defined containers. So I think that this enhancement has a bias toward range concept. And, as far as possible, compiler should be a neutral. In other words, this is just reasonable for std.range users. Most of D programmers would use std.range, but not all.There is no intent to cover infinite forward ranges with default behavior. Again, the primary goal here should be, I think, to make code defining casual ranges easy and boilerplate-free. Infinite ranges or ranges that don't define length yet want to define slicing through to the end are comparatively rare. It is reasonable to request people defining those to define opDollar appropriately.I don't mention that infinite range _should_ have r[n..$], rather mention that it is possible.If we go for a library solution, we should define opDollar in object.d so it's available by default. It should look something like this (in the 1-dimensional case): auto ref opDollar(R)(auto ref R r) if (is(typeof(r.length))) { return r.length; }This is bad. druntime should not have things for range concept. It is a job of std.range. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 11:04:45 PDT ---I don't think there's any breakage. My understanding is that those containers already need to define opDollar. If opDollar is defined there is no change in semantics.Kenji: I'm a bit unclear on your view on this. You mention you'd prefer a library solution but your pull request seems to go for a in-compiler solution.'length' would break user-defined containers.The fact clearly represents that we cannot always regard $ as "length". Indeed, it is true in built-in arrays and range concept, but isn't true in associative arrays and some user-defined containers. So I think that this enhancement has a bias toward range concept.I'd have quite a bit of difficulty agreeing with this. The notion that "$" is a synonym for "length" predates ranges and has been there for strings and arrays ever since they were defined. On the contrary, I'd argue that notions such as length-less ranges and infinite ranges contributed to the notion that opDollar may be (rarely) something distinct from length.And, as far as possible, compiler should be a neutral.That shouldn't be done to a fault, either. The D language is not neutral on user-defined expr++ vs. ++expr; it forces both to have similar semantics to their built-in counterparts. In contrast, the C++ language allows defining ++expr and expr++ with different semantics. But wait, it's worse: (a) C++ forces a net loss of efficiency for expr++ barring heroic optimization efforts that are not generally applicable, and (b) C++ requires actual boilerplate to ensure both variants work. I think it is plain that C++ made the wrong decision and D learned from it and made the right decision. Similarly, we should not require boilerplate for $ just to convince it to do what it's always done for arrays and strings. Associative arrays and user-defined containers are free to disable it or define it, depending on what's most useful for them.In other words, this is just reasonable for std.range users. Most of D programmers would use std.range, but not all.Again, I find it very difficult to agree with this. $ has always been length wherever meaningful - long before ranges came up.I don't mention that infinite range _should_ have r[n..$], rather mention that it is possible.Yes, and defaulting $ to length does not prevent that. Again, if a range does define opDollar, that will always be chosen. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---I don't think there's any breakage. My understanding is that those containers already need to define opDollar. If opDollar is defined there is no change in semantics.No. This enhancement will suddenly change a "correctly invalid" code to "accepts-invalid". SparseArray a; // SparseArray does not have opDollar, // because it is unnecessary now. auto n = a.length; // actually contains element count, or maximum index number a[$-1]; // now: Error: undefined identifier __dollar // after: incorrectly translated to a[a.length-1]; Finally SparseArray's author should add disable opDollar()."$" is a synonym for "length" in D - yes. But, **in general**, "$" is not a synonym for "length". The difference is important. The advantage of UFCS and std.range.opDollar approach is that is "opt-in" for the "$" meaning. It does not change the meaning of current existing code. (Again, "change" == "currently invalid/meaningless code will be changed to acceptable, potentially and unintendedly") On the other hand, your compiler approach is "opt-out". It moves boilerplate code from all range definition to SparseArray definition. This is unacceptable to me.The fact clearly represents that we cannot always regard $ as "length". Indeed, it is true in built-in arrays and range concept, but isn't true in associative arrays and some user-defined containers. So I think that this enhancement has a bias toward range concept.I'd have quite a bit of difficulty agreeing with this. The notion that "$" is a synonym for "length" predates ranges and has been there for strings and arrays ever since they were defined.It is entirely different thing.And, as far as possible, compiler should be a neutral.That shouldn't be done to a fault, either. The D language is not neutral on user-defined expr++ vs. ++expr; it forces both to have similar semantics to their built-in counterparts. In contrast, the C++ language allows defining ++expr and expr++ with different semantics. But wait, it's worse: (a) C++ forces a net loss of efficiency for expr++ barring heroic optimization efforts that are not generally applicable, and (b) C++ requires actual boilerplate to ensure both variants work. I think it is plain that C++ made the wrong decision and D learned from it and made the right decision.Similarly, we should not require boilerplate for $ just to convince it to do what it's always done for arrays and strings. Associative arrays and user-defined containers are free to disable it or define it, depending on what's most useful for them.Why you enforce disabling opDollar to other container authors? It is equivalent to enforce writing "alias opDollar = length;` to all range authors. I cannot see any difference there. If you favor the former, I can say it is definitely a kind of bias. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 17:30:22 PDT ---Understood. I would argue that behavior changes from "invalid" to "valid and correct". I think it would be hard to find one D programmer who'd write s[$ - 1] and expect it to be anything else than a[a.length - 1]. This behavior has been built in forever. Whether SparseArray should support operator [] and length are separate questions. If it does, and if anyone ever writes a[$ - 1], that should be correct code and there is no other possible semantics than a[a.length - 1].I don't think there's any breakage. My understanding is that those containers already need to define opDollar. If opDollar is defined there is no change in semantics.No. This enhancement will suddenly change a "correctly invalid" code to "accepts-invalid". SparseArray a; // SparseArray does not have opDollar, // because it is unnecessary now. auto n = a.length; // actually contains element count, or maximum index number a[$-1]; // now: Error: undefined identifier __dollar // after: incorrectly translated to a[a.length-1]; Finally SparseArray's author should add disable opDollar().Agreed.I'd have quite a bit of difficulty agreeing with this. The notion that "$" is a synonym for "length" predates ranges and has been there for strings and arrays ever since they were defined."$" is a synonym for "length" in D - yes. But, **in general**, "$" is not a synonym for "length". The difference is important.The advantage of UFCS and std.range.opDollar approach is that is "opt-in" for the "$" meaning. It does not change the meaning of current existing code. (Again, "change" == "currently invalid/meaningless code will be changed to acceptable, potentially and unintendedly")I'd say the change is to a behavior that has a null surprise factor. If anyone writes a[$ - 1] or whatnot, it is clear what they meant and what they expect.On the other hand, your compiler approach is "opt-out". It moves boilerplate code from all range definition to SparseArray definition. This is unacceptable to me.Let me submit for your consideration that (a) it's undecided whether that's bad for SparseArray, and (b) the vast majority of ranges simply want opDollar be the same as length. This is the case for all of Phobos, and this bug originated in wake of a large diff that added very many "alias length opDollar;" to virtually all ranges that support [] and length. It's just what everybody expects. I would argue we can't afford to make everybody pay for the sake of a rare occurrence.I agree it is a different thing. I was replying to the part with "As far as possible, compiler should be neutral" by simply showing that sometimes being neutral is exactly the wrong thing to do.It is entirely different thing.And, as far as possible, compiler should be a neutral.That shouldn't be done to a fault, either. The D language is not neutral on user-defined expr++ vs. ++expr; it forces both to have similar semantics to their built-in counterparts. In contrast, the C++ language allows defining ++expr and expr++ with different semantics. But wait, it's worse: (a) C++ forces a net loss of efficiency for expr++ barring heroic optimization efforts that are not generally applicable, and (b) C++ requires actual boilerplate to ensure both variants work. I think it is plain that C++ made the wrong decision and D learned from it and made the right decision.I think most container authors will benefit of that behavior.Similarly, we should not require boilerplate for $ just to convince it to do what it's always done for arrays and strings. Associative arrays and user-defined containers are free to disable it or define it, depending on what's most useful for them.Why you enforce disabling opDollar to other container authors?It is equivalent to enforce writing "alias opDollar = length;` to all range authors. I cannot see any difference there. If you favor the former, I can say it is definitely a kind of bias.Yes, there is a bias - frequency. My core argument is that the vast majority of ranges simply want $ and length to mean the same thing, and very few need to have them mean different things. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Yes, there is a bias - frequency. My core argument is that the vast majority of ranges simply want $ and length to mean the same thing, and very few need to have them mean different things.I have lost part of the track of this long thread. Adding one alias to a whole class/struct container is a really small amount of simple boilerplate code. So I think having to add it is not bad. On the other hand in most cases such alias is desired, so it's good for it to be the default, and have some syntax (even a longish one) to disallow it in the rare cases when it's not desired. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177... Yes, there is a bias - frequency. My core argument is that the vast majority of ranges simply want $ and length to mean the same thing, and very few need to have them mean different things.His proposal is to make it work for all ranges. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 05:19:35 PDT ---Not sure I understand. It's possible I am confused. Could you please summarize what you mean giving some more context? Thanks. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------... Yes, there is a bias - frequency. My core argument is that the vast majority of ranges simply want $ and length to mean the same thing, and very few need to have them mean different things.His proposal is to make it work for all ranges.
Apr 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177Your proposal is to make opDollar refer to length whenever there is a length, auto ref opDollar(R)(auto ref R r) if (is(typeof(r.length))) { return r.length; } by default allowing things like: int[int] x = [1:0,3:2]; x[$]=1; assert(x==[1:0,2:1,3:2]); As far as I understand it, his proposal is to restrict $ to ranges. auto ref opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } std.range vs. object.d is a separate issue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Not sure I understand. It's possible I am confused. Could you please summarize what you mean giving some more context? Thanks.... Yes, there is a bias - frequency. My core argument is that the vast majority of ranges simply want $ and length to mean the same thing, and very few need to have them mean different things.His proposal is to make it work for all ranges.
Apr 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177... As far as I understand it, his proposal is to restrict $ to ranges. ...Unlucky formulation. It should read "to restrict the default opDollar to ranges". -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 04:06:03 PDT ---Your proposal is to make opDollar refer to length whenever there is a length, auto ref opDollar(R)(auto ref R r) if (is(typeof(r.length))) { return r.length; }Well whenever there's a length and [].by default allowing things like: int[int] x = [1:0,3:2]; x[$]=1; assert(x==[1:0,2:1,3:2]);That's not necessarily the case. Under the proposed semantics built-in hash tables would disable opDollar. BTW disabling opDollar should mean "pass through". Consider: import std.stdio; void main(){ int[size_t] a; int[] b = [ 1, 2, 3, 4, 5 ]; a[5] = 1; a[2] = 2; writeln(b[a[a.length]]); writeln(b[a[b.length]]); writeln(b[a[$]]); } This program prints "3 2 2" so the $ is transparently interpreted as the array's length. I'm not a fan of that particular behavior, but probably we need to preserve it.As far as I understand it, his proposal is to restrict $ to ranges. auto ref opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } std.range vs. object.d is a separate issue.Is that correct, Kenji? (I don't think we should mix ranges into this without necessity.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 ---BTW disabling opDollar should mean "pass through". Consider:I think it would introduce one more "special case" in operator overloading mechanism. I hate special rules.Yes. It is correct. See my experimental implementation.As far as I understand it, his proposal is to restrict $ to ranges. auto ref opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } std.range vs. object.d is a separate issue.Is that correct, Kenji? (I don't think we should mix ranges into this without necessity.)https://github.com/9rnsr/dmd/branches/fix7177alt https://github.com/9rnsr/phobos/branches/fix7177althttps://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1326 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 07:47:20 PDT ---I agree this is a good counter-argument to my proposed approach.BTW disabling opDollar should mean "pass through". Consider:I think it would introduce one more "special case" in operator overloading mechanism. I hate special rules.Yes. It is correct. See my experimental implementation.As far as I understand it, his proposal is to restrict $ to ranges. auto ref opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } std.range vs. object.d is a separate issue.Is that correct, Kenji? (I don't think we should mix ranges into this without necessity.)I think this is a good compromise. Unless there are other issues found by others, I agree moving forward with this. More thoughts? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------https://github.com/9rnsr/dmd/branches/fix7177alt https://github.com/9rnsr/phobos/branches/fix7177althttps://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1326
Apr 02 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 07:48:14 PDT ---I meant to insert "I agree this is a good counter-argument to my proposed approach." here! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------BTW disabling opDollar should mean "pass through". Consider:I think it would introduce one more "special case" in operator overloading mechanism. I hate special rules.
Apr 02 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177So to wrap things up, both for myself or those who have lost track: What we are finally doing is allowing opDollar (and only opDollar) to be implemented UFCS style, correct? Then, inside std.range, we provide a "global range" opDollar function. This will mean that ranges (and only ranges) will have $ => length? Is this correct so far? And in the special case of infinite ranges, it will convert to an empty object (Infinity)? Sounds good to me. We'll just have to keep in mind that: a) $ will be automatically provided *only* if the user imports std.range (failure to import it will mean failure to use opDollar) b) Implementations may still want to explicitly provide the alias, for "native" opDollar: std.range.opDollar will only be "fall back" implementation. To be frank, I'm 100% fine with that. Other than that: Nitpick time! 1) The "Infinity" struct name is pretty vague. J.M. Davis and I have been using the term "DollarToken" so far. Any chance we use that instead? It has the advantage of being bound to the word "dollar". It can also be used for non-infinite ranges that still want to exploit end slicing. 2) I think providing opDollar for InputRanges (as opposed to ForwardRange) is better. I don't see why we'd want to go out of our way to cripple InputRanges. That's it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------https://github.com/9rnsr/phobos/commit/dd0d4c139828013c34e76acc74884341f31db298#L0R1326I think this is a good compromise. Unless there are other issues found by others, I agree moving forward with this. More thoughts?
Apr 02 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7177 08:36:58 PDT --- FWIW, if it's not apparent from all I've said in the past, I'm on board with the proposed compromise. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 03 2013