digitalmars.D.bugs - [Issue 9786] New: Allow [non-member|UFCS] implementation of operators
- d-bugmail puremagic.com (34/34) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (33/33) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (12/12) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (9/13) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (11/12) Mar 22 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (30/30) Mar 23 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (23/26) Mar 30 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (30/54) Mar 30 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
- d-bugmail puremagic.com (30/30) Mar 31 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9786
http://d.puremagic.com/issues/show_bug.cgi?id=9786 Summary: Allow [non-member|UFCS] implementation of operators Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: monarchdodra gmail.com UFCS has made it possible for anyone to "expand" a type, by giving it new functions, or new properties. One of the rationales is that it improves encapsulation by not having to worry on if or if not some function is member or global. It also improves encapsulation by allowing expanding a type externally. However, the line is drawn at operators: These may *only* be implemented as member functions. I see no real reason for this limitation. Issue 7177 has shown a (very) strong need for the ability to implement opDollar via non-member: http://d.puremagic.com/issues/show_bug.cgi?id=7177 One of the reasons for not implementing non-member operators is that it would grant the ability to add operators on built in type. I think that: a) If user wants to do something stupid, that's his problem. b) If we so desire, I'm sure the compiler could be more than powerful enough to implement " disable opBinary" for any operator it does NOT want implemented ever (eg string + string). Since the lookup rules are chose member function first, this would not even be a "special case". Anyways, yeah: non-member operators. We need them, and they make sense (IMO). In particular, opDollar, since it is a property operator. -- 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=9786 Extracted from 7177, this is an example of how and why we'd want this: //-------- import std.stdio; import std.range; //opDollar for any range with length auto opDollar(R)(auto ref R r) if (isInputRange!R && hasLength!R) { return r.length; } //RA range that does not define opDollar 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[$]); //Works } //-------- -- 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=9786 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmx.com PDT --- Personally, I think that it's a terrible idea to be able to add overloaded operators to a type with 3rd party code, but with UFCS, it would be even worse, because as soon as you had a conflict, there would be no way to resolve it. -- 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=9786Personally, I think that it's a terrible idea to be able to add overloaded operators to a type with 3rd party codeWhy would it be any worst than what we have with UFCS?but with UFCS, it would be even worse, because as soon as you had a conflict, there would be no way to resolve it.That's a good point. Unless you call the operator directly, eg: lib.opBinary!"+"(a, b), but that's ugly as sin. -- 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=9786 Andrej Mitrovic <andrej.mitrovich gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrej.mitrovich gmail.com 15:28:02 PDT ---a) If user wants to do something stupid, that's his problem.That's not a good way to look at it, a 3rd party library could implement a non-member operator without the user knowing. -- 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=9786 Maxim Fomin <maxim maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maxim maxim-fomin.ru --- Operator overloaded methods are special functions. There are several problems with UFCSising them. 1) When there is conflict between different functions across several modules, it is easy to overcome the problem by renaming functions. If you have two opCalls for structs (for example) in two different modules and if you try to use them simultaneously, any code like S() is broken and have to be rewritten. Worse may happen with opBinary like in S a, b; .. a = a + b; Now opBinary is hijacked by something else and code is fundametally broken. Rewriting a+b is not the same as rewriting a.foo(). And in presence of regular function name conflict it is possible to rename for ex. foo() to myFoo() and be happy, but it is not posssible to have a +myOpBin b, so overloading operator immediatly loses its sense. 2) Druntime may dependend on operator overloading functions. When you try to UFCSizly overload operator, and get return value from function which was compiled when operator was not overloaded (due to separate compilation model), you may have logically incorrect value: you expect that operation was performed with overloaded operators but actually it was not the case. In general, I prefer to leave overloading decision to owner of the type. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9786 timon.gehr gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr gmx.chOperator overloaded methods are special functions.No, they are specially named normal functions with some syntax sugar support. They can just as well be called as normal functions/methods. In this case, UFCS already works.There are several problems with UFCSising them. ...There are no issues not common to other functions. Operator overloading is all about syntax. It is completely pointless to single out the operator overloading functions in any other way. The objections are simply invalid: 1) (template) functions can always be renamed, even if they happen to be named eg. opBinary. 2) Druntime will _never_ catch up UFCS (template) functions anyway. It does not matter if they are called eg. opUnary or toString. BTW, I do not think this is an enhancement. According to the online docs and TDPL, it should work. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 30 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9786 ---This is exactly why they are special - because some language constructs are transformed to them (they have "some syntax sugar support"). Other methods do not have such feature. Besides, UFCS allows simply to transform function call to method call, it does not promise to support "some syntax sugar" of some "specially named normal functions" beyond its scope.Operator overloaded methods are special functions.No, they are specially named normal functions with some syntax sugar support. They can just as well be called as normal functions/methods. In this case, UFCS already works.Nobody tries to single out them. They are already singled outed by the fact of their existence.There are several problems with UFCSising them. ...There are no issues not common to other functions. Operator overloading is all about syntax. It is completely pointless to single out the operator overloading functions in any other way.The objections are simply invalid: 1) (template) functions can always be renamed, even if they happen to be named eg. opBinary... in general case when you have ordinal method. Renaming foo() to myFoo() is not a big deal. Renaming a[i[$]] = b[] in terms of explicit opSlices and opIndexes is not that fruitful. What's more, in case of foo() => myFoo() UFCS is still useful, while in case of a[i[$]] = b[] => opSlice etc. you cannot write nice expressions (no way for +mybin operator), so supporting this feature loses sense. In short, making UFCS to support "some syntax sugar" beyond its purpose is a feature which can be easily abused and broken, so why should it be supported?2) Druntime will _never_ catch up UFCS (template) functions anyway. It does not matter if they are called eg. opUnary or toString. BTW, I do not think this is an enhancement. According to the online docs and TDPL, it should work.This was not supposed to work. UFCS was made to perform simple method transforms. Transforming expressions info function calls is separate issue. Some programmers demand this feature because they considered it as a "cool" due to "some syntax sugar support". The problem is that some others also think so and start to overload. And since the amount of just "specially named normal functions" is fixed and limited, probability to run into conflict with opWhatever is higher than in case of ordinal method. Nicest case happens when they overload operator methods simultaneously in independent modules and somebody decided to use each of the modules. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 30 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9786 std.typecons.Proxy is incorrect because of this inconsistent behaviour of DMD: import std.conv, std.typecons; struct S{ int x; } int front(ref S s){ return s.x; } bool empty(ref S s){ return s.x>10; } void popFront(ref S s){ s.x++; } auto opBinary(string op)(S a, S b){ return S(mixin("a.x "~op~"b.x"));} struct Capture(T){ private T payload; mixin Proxy!payload; } auto ufcs(T)(T arg){ Capture!T r; r.payload = arg; return r; } import std.stdio; void main(){ auto s = S(3); writeln(s.ufcs); // [3, 4, 5, 6, 7, 8, 9, 10] writeln(s.opBinary!"+"(s)); // S(6) //writeln(s.ufcs.opBinary!"+"(s.ufcs)); // error! } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2013