possible "solution" for ufcs

KennyTM~ kennytm at gmail.com
Mon Jun 6 12:27:21 PDT 2011


On Jun 7, 11 03:00, 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

Maybe better

     auto ref opDispatch(string name, T...)(auto ref T args) {
         mixin("return ." ~ name ~ "(this, args);");
     }

so that ref-returns and ref-parameters can be handled as well. Doesn't 
work for 'lazy' though. It also cannot preserve 'pure'-ity, 
'nothrow'-ness and '@safe'-ty of the original function.



More information about the Digitalmars-d mailing list