UFCS and constructors

Timon Gehr timon.gehr at gmx.ch
Tue Jul 2 19:54:41 PDT 2013


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.



More information about the Digitalmars-d mailing list