On 07/03/2013 04:12 AM, Jonathan M Davis wrote:
On Wednesday, July 03, 2013 04:00:45 bearophile wrote:
deadalnix:
The whole point of UFCS is to be able to provide additional
custom "methods" to a object (class or struct). Constructor
UFCS don't fulfill that use case.
Nothing is removed from the language as factories method can be
introduced anyway.
This frames the topic in a wrong way. Constructors are not normal
functions, they are special, but functional languages show us
that's it's a very good idea to see them as functions.
And the original point of UFCS doesn't matter much. What matters
is what are the practical disadvantages of allowing UFCSyntax for
constructors (like the original post in this thread), and what
are their practical advantages/uses (like a handy usage in UFCS
chains). Then we take a look at what's the resulting balance and
we decide. And such decisions should then become the written
specifics of this part of the D design.
The primary benefit of UFCS is generic code, because if uses UFCS, generic code
doesn't have to care whether a function is a member function or a free
function (particularly when that can vary drastically depending on what type
is used to instantiate the template).
No. Generic code has to be careful with UFCS, because every method that
is called on a suitable variable via UFCS can be (accidentally) replaced
by the client code.
Construction is not and cannot be generic.
The point is that struct constructors can be generically used like other
callables.
import std.stdio, std.algorithm;
struct S{
int x;
}
void main(){
auto x = [1,2,3];
writeln(x.map!S);
}
There is nothing to be gained from subtly breaking this analogy. UFCS
can be applied to any callable.
You are probably not going to like this, but the following code also works:
import std.stdio;
struct S{
int opCall(int x){ return x+1; }
}
S s;
void main(){
auto x = 1;
writeln(x.s);
}
The closest that you could get would be a factory function, which is
quite different. But constructors themselves cannot be generic. As such, using
constructors with UFCS in generic code just doesn't work, meaning that the
only gain that you're getting from using UFCS with constructors is that you
get a slightly different syntax that you might like better for one reason or
another. But I see no technical reason why it could add any benefit over simply
calling the constructor normally. And as such, I think that allowing UFCS to
work with constructors is definitely an anti-feature.
...
To be an anti-feature it has to be harmful, not just of less benefit
than some other (aspect of the) feature.