Steven Schveighoffer wrote: > Someone wrote a very compelling argument for ufcs (uniform function call > syntax) for ranges, and that is, given a slew of range functions, and a > slew of ranges, it is nice to use a fluent programming syntax to specify > wrappers for ranges without having to extend each range type. For example: > > take(10,stride(2,cycle([3,2,5,3]))); > > vs. > > [3,2,5,3].cycle().stride(2).take(10); > > And I thought damn it would be nice if ranges could implement ufcs, but > other types that you didn't want to allow infinite extendability could > avoid it. That gave me an idea :) > > > import std.stdio; > > struct ufcs > { > auto opDispatch(string name, T...)(T args) // appropriate if compiles > constraint here > { > mixin("return ." ~ name ~ "(this, args);"); > } > } > > int foo(ufcs x, int y) > { > writefln("it works! %d", y); > return y+1; > } > > void main() > { > ufcs u; > auto x = u.foo(1); > assert(x == 2); > } > > And it does indeed work (2.053)... > > So we can have ufcs without any changes to the compiler, and we also make > it a *choice* for people who don't want to allow infinite extendability, > and don't want to deal with possible compiler ambiguities. > > The opDispatch could even be a mixin itself (I think). > > What do you think? > > -Steve
Great! =) This resolves everything around UFCS! Why has nobody come up with this before? You should definitely file an enhancement request for phobos. We just add something like this somewhere: mixin template implementUFCS() { auto opDispatch(string name, T...)(T args) if(is(typeof({mixin("return ." ~ name ~ "(this, args);");}))){ mixin("return ." ~ name ~ "(this, args);"); } } Each range type will do mixin implementUFCS; And we'll have optional UFCS!!! A little drawback: Types using implementUFCS will have very bad error reporting if somebody types a member name wrong: struct foo{mixin implementUFCS;} int main(){foo x;x.bar();} Error: template instance opDispatch!("bar") does not match template declaration opDispatch(string name,T...) if (is(typeof(delegate () { mixin("return ." ~ name ~ "(this, args);"); } ))) I think here a change to the compiler would be appropriate at some point so that we can get: Error: no property 'bar' for type 'foo' If opDispatch does not match. But this is definitely the way to go for UFCS! Timon