UFCS and constructors

monarch_dodra monarchdodra at gmail.com
Wed Jul 3 08:04:24 PDT 2013


On Wednesday, 3 July 2013 at 03:22:16 UTC, Jonathan M Davis wrote:
> On Wednesday, July 03, 2013 04:54:41 Timon Gehr wrote:
>> 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.
>
> That's the whole point! If you absolutely have to be certain 
> that it's not
> calling a free function, then don't use UFCS, but the primary 
> benefits of UFCS  
> are making it so that generic code doesn't have to care whether 
> a function is
> a free function and making it so that types can overload the 
> behavior of free
> functions (e.g. having a member function find which is 
> optimized for that type
> and can be used in place of std.algorithm.find).
>
>> > 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);
>> }
>
> That is _very_ broken IMHO. It makes no sense for parens to be 
> optional with
> opCall. The whole point of opCall is to overload the parens!
>
> - Jonathan M Davis

In a UFCS chain, it would make sense for the so-called "function 
object":

struct Incrementor
{
     int n;
     ref int opCall(ref int i)
     {
         return i+=n;
     }
}

int i, j;
auto incrementByTwo   = Incremementor(2);
auto incrementByThree = Incremementor(3);
i.incrementByTwo;
j.incrementByThree;

Here, the "function object" is treated just like a function (it 
is *designed* to behave like a function), so it should benefit 
from the same optional parens as a normal function.

However, yeah, I think a standalone arg-less opCall with no 
parens is stupid (unless someone has a usecase for it?): It's an 
alias this in disguise, nothing more.


More information about the Digitalmars-d mailing list