On Fri, 25 Apr 2014 00:58:51 -0400, Jonathan M Davis via Digitalmars-d <digitalmars-d@puremagic.com> wrote:


If it doesn't work to override a free function with a member
function, I honestly don't see much point to UFCS. The whole idea
behind it is to make it so that you don't have to care whether a
function is a free function or a member function. The current situation
essentially forces you to not use UFCS except in cases where you're
trying to add "member functions" to built-in types. And as such,
calling functions on user-defined types using UFCS runs a high risk of
not compiling, because all it takes is for the user-defined type to
define a function with the same name - even if it takes completely
different arguments - and now the compiler won't even try to use the
free function anymore.

Right but the pattern is:

someGlobal(T t, U u)
{
   static if(is(typeof(t.someGlobal(u))))
     t.someGlobal(u);
   else
     // use default implementation.
}

Essentially, someGlobal is encouraging not only overriding itself for a type, but for only a PORTION of the implementation.

If you override put completely, allowing all the mechanisms put uses, that is absolutely fine. But for only implementing a single part, the hook put uses to interface with the type should NOT be named put. This means the member put is far less functional than the global function put.

What I'm saying is that the hook and the global function should not be named the same. Not that we should change the override rules.

I really think that we should fix it so that stuff like
outputRange.put(foo) works - including when types define put
themselves. AFAIK, that means changing the overload rules so that
member functions conflict with free functions only when they take the
same arguments - in which case the member function would be called, as
it is now, except that the cases where a free function matches the
arguments would also work, allowing us to override free functions with
member functions where appropriate and prevent simple name collisions
from making UFCS not work (i.e. when the member function takes
completely different arguments, UFCS would still use the free
function). Without a change along those lines, I'd be strongly inclined
to argue against using UFCS in any situation except in those where you
need to add "member functions" to the built-in types. And the only
common case for that that I'm aware of is making it so that arrays can
function as ranges.

I don't think this is a good idea. A type first and foremost is in charge of its API.

Another possible option is to make sure put(R, ...) is as limited as the member R.put(...). This means, if R.put doesn't support the parameters, put(R, ...) should also reject them.

This at least is consistent, but I think code will break for not much of a good reason.

-Steve

Reply via email to