On Sunday, 14 October 2012 at 20:15:15 UTC, Tommi wrote:
On Sunday, 14 October 2012 at 07:14:25 UTC, Maxim Fomin wrote:
If this request is approved and compiler has opUnary
definition outside type (which suits better then alias
this) such function would hijack alias this.
Free functions cannot and must not ever hijack, i.e. modify
existing functionality of a type. Free functions should only be
able to add new functionality to a type. This is what currently
happens with alias this vs free function which is accessed
through UFCS:
<snip>
This shows current behavior. The issue is future behavior of code
like this:
---foo.d---
struct A
{
int i;
alias i this;
}
---bar.d---
int opUnary(string T)(A a) { ... }
...
{
++a;
}
-----------
I. i is incremented, opUnary is not called. However opUnary
matches better to the actual type and if it were a method, it
would be called - another special issue in the language which
breaks usual logic. And if you declared opUnary in bar.d when
alias this was absent in foo.d and later added - hijacking also
occurs but now it happens from another side. Bad.
II. opUnary is called, i is not incremented. On the one hand you
get what you wanted - you supplied opUnary and it is called. At
least this is consistent with matching behavior. On the other
hand, it is hijacking from position of foo. Bad.
III. Compiler issues error if you try to define some free
functions which are similar to existing methods (code above is
particular case) or if you declare operator overloading methods
in the presence of alias this. This prevents from making
confusion but if you link to some library, update code and its
author defines new method, which is similar to your UFCS
function, you get errors and have to rewrite code.
IV. Do nothing and leave things as they are. Presence of opUnary
function doesn't affect operator overloading. While current UFCS
behavior falls in the first category (newly created foo.d methods
hijack bar's free functions) there are no such problems with
operator overloading methods. And operator overloading requires
methods, not just free functions. Although methods and free
functions may be called similar in source code, they still are
different - in runtime calling, in mangling, in requiring
contract invocation, argument passing, etc.