On Thu, 03 Feb 2011 16:05:01 -0500, spir <denis.s...@gmail.com> wrote:

On 02/03/2011 08:43 PM, Steven Schveighoffer wrote:
The more I think about it (and read discussions like this), the more I think that uniform call syntax should only be allowed for types which cannot declare member functions (arrays, primitives, enums, etc.). Otherwise, we introduce
new ambiguities that serve little purpose except annoyance.

More precisely, it should work with all types in position of first parameter, but using implicit this like with member functions. This is ok:
     void f (C c, I i) {...}
     auto c = new C();
     I i;
     c.f(i);
Don't you think so?

But what if C also defines f? I don't think c.f(i) should fail in that case. If it doesn't fail, then surprises/hijacking will occur (hey, I thought I was calling my f, what gives?!). You could write code like this:

import std.somemodule : A;

void f(A a, int i) {...}

void foo()
{
  auto a = new A;
  a.f(1);
}

and then some day, the author of std.somemodule now decides he wants to add a member function f(int). All of a sudden, all places you use a.f now mean something else (dangerous). This is unacceptable. It's also unacceptable for a.f to call your f (confusing/ambiguous, sometimes a.f means your f, sometimes it means the member), or to have the compiler error (annoying). I don't see any good solution to this, except to say, "nope, you just gotta write f(a, 1), tough shit."

I really don't understand the benefit of allowing a.f instead of f(a), it's a *trivial* gain at best. Note that if I see your code, I'm going straight to the definition of A to try and find the f member function. If I can't find it there, with UFC syntax, it could be anywhere.

OTOH, adding member functions to types that don't allow members, although equally as trivial (find(str, "hi") vs. str.find("hi") ), at least is not ambiguous :)

-Steve

Reply via email to