Am 06.06.2011 21:38, schrieb Monkol:
On Mon, 06 Jun 2011 22:00:13 +0300, Steven Schveighoffer
<[email protected]> 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


what this code must to do?

opDispatch is special template member a class or struct can have. When using the dot-operator to acces members and these aren't there, opDispatch!"memmbername" is tried. Now when ou try to use uniform function call syntax (UFC) on a struct, the function-as-method you want to use is not in the struct but in the module-scope. The compiler therefore can't find any memeber and tries opDispatch which itself tries to resolve to a module-scope function using the leading dot. Through ct-string-operations and mixin the name of the function gets injected into the code.
I hope I could help you.

Mafi

Reply via email to