Is @property implementable?

Kevin Bealer kevindangerbealer at removedanger.gmail.com
Fri Mar 4 00:31:37 PST 2011


== Quote from Jonathan M Davis (jmdavisProg at gmx.com)'s article
> But that's not how the function is written. The left parameter is the
> destination. If myString.strcpy(myString2) is confusing, I would expect
> strcpy(myString, myString2) to be just as confusing. I don't see how using the
> member function call syntax like that makes it any more confusing. Not to
> mention, functions with a source and destination like that end up in both orders
> all the time, so I don't think that you can generally expect it in one order or
> the other anyway.
> - Jonathan M Davis

I personally think strcpy got it wrong anyway -- everyone says 'input and output',
not 'output and input', so it's weird to think of the output mentioned first.
It's as if you wrote:

// everyone who uses this will get the argument order wrong at least once
int everythingNice(int spice, int sugar);

But that's a side note...

Personally, I think the UFCS for anything but arrays is an engraved invitation to
function hijacking.  Imagine defining this in your code:

int find(T, U)(T a, U b)
{
    ...
}

class Foo {
    int find(double x, char[] y);
};

Foo x;
x.find(a, "hello"); // would this call the template or the method?

Whoops -- now every class, structure, and array in your program has a method
called find() that hijacks any arguments that don't exactly match an existing
function.  If you call x.find(), you can't know if you are getting the method in
the class or a free function that got sucked in because of this syntax.  Of course
if you get the signature exactly right it probably prefers the method over the
free function.  Arrays are special because the only methods they have are *built
in* methods.  Thus, a basic understanding of the language makes it possible to
avoid the ambiguity.  But implementing UFCS for other types is a problem.

If I do "a.getIndex(5)" and the compiler says there is no method getIndex on class
A, this is a gift --- it is almost always the case that this is an error.  I doubt
I ever want getIndex(A, int) but wrote A.getIndex(5) or where I wanted f(A, int)
but wrote a.f(5).

If you want another method in your class *add it to your class*.  The reason it
makes sense to have it for arrays is so that you can define common methods across
all your types like "serialize" method or "toString" or "deepCopy" and know what
these methods do.  Then you can use them in templates.  Arrays can't be subclassed
to add the methods so you need a way to produce the same syntax as a method call.

Since arrays can't be derived from, UFCS fills in a real gap and doesn't mask
existing or future methods unless the interface for arrays changes which is rare,
we hope.  Allowing it for other types doesn't fill a gap, it creates an
overlap/ambiguity.  It doesn't let you do anything you can't already do.  It's
like a built-in alias this that you can't turn off and that matches across all the
free functions of the world if I'm understanding the matching correctly.

In most cases you can also use functions (for deepCopy etc) to work with both
classes and arrays, but this doesn't work with virtual functions, so the method
syntax is nicer for that.  So UFCS is justified to make arrays 'look like classes'
to template code.  But it's not justified in my opinion to make classes look like
classes with one more method.

Kevin


More information about the Digitalmars-d mailing list