On Monday, 15 October 2012 at 11:01:13 UTC, Artur Skawina wrote:
UFCS has pros and cons. I could agree that it has problems and should be removed from the language completely. But if the feature is there, it should work, w/o any
unnecessary special cases.

Special cases would be created by any decision, the only question is which feature is discriminated - alias this, UFCS or something else (currently UFCS is).

An overloaded operator is just another normal method; you get the same type of problems when dealing with "normal" methods - eg in types having an "alias this" - an UFCS "method" must take precedence over one reachable via the alias - just like in the overloaded op case. The only sane alternative would be disallowing UFCS for types with an "alias this" (which would be a severe limitation).

You seem to be in the second camp (UFCS free function takes precedence over alias this, if declared). I am not against, just to note.

And the purpose of UFCS is?... "operator overloading methods" are /not/ special.
artur

The point is that when you want to define UFCS free functions like opUnary, you want not only to call them like a.opUnary!"++"() but to code like ++a. That is the key issue here and that makes the whole case special.

In other words: with UFCS you have an option: to call your function as it was a method of some type. And anyone has this option. The only problem is namespace conflict which can be easily avoided. But you still has the option. With UFCS operator overloaded functions you have *two* options: to call free functions as methods as usual *and* to use struct/class with many operators in a manner you want. But if anyone of that type users define his set of operator overloaded functions *you lose the second option* which makes the proposal to allow simultaneous access to single resource pointless.

Consider this:

---somelib.d---
struct A { void foo() {} }

---otherlib.d---
void bar(A a) {}

---mycode.d---
// blah, foo and bar are taken
// solution - choose other name
void baz(A a) {}
---------------

Now assume, UFCS operator overload is possible.

---somelib.d---
struct A { int i; int j; }

---mycode.d---
int opUnary(string T : "++")()
{
    return ++i;
}
...
++a;
...
-------------

At some point of time the owner of somelib.d changes code (or anyone whom code you import define such functions):

---somelib.d---
struct A {
int i; int j;
int opUnary(string T : "++")()
    {
        return ++j;
    }
}

---mycode.d---
int opUnary(string T : "++")()
{
    return ++i;
}
----------------
So, you lost your option to use A in expressions and call your function which is the point here. You cannot invent +my_unary+ operator. Neither you can rebind ++ to some function other than opUnary.

Yes, it also may happen with regular function, when you lose ability to give a function some specific name you want (like "create", "foo" etc.). But in case of UFCS operators you lose not only some function name ("opUnary") but corresponding expression as well (++).

This means that it makes sense to allow only one set of opUnary/opBinary/.. etc. of functions (anyway, only one can define them and use with operators) and the most suitable place is declaration of their type.

Reply via email to