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! > > 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. I _do_ think that it's harmful. It obfuscates code without adding any benefit. - Jonathan M Davis