Address of UFCS call implicity converts to Delegate

Jonathan Marler via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 24 08:47:14 PDT 2017


On Sunday, 23 April 2017 at 17:13:31 UTC, Basile B. wrote:
> On Sunday, 23 April 2017 at 17:07:51 UTC, Jonathan Marler wrote:
>> On Sunday, 23 April 2017 at 17:00:59 UTC, Basile B. wrote:
>>> 2/ Why not just a member function ?
>>
>> For the same reason that UFCS exists.  You can't add "member 
>> functions" to external library types.
>
> Good point. I have to say that this feature then makes me think 
> to what's called "class helpers" in the Delphi/Object Pascal 
> world. That's exactly for what they're used.

I've added a DIP for this (https://github.com/dlang/DIPs/pull/61).

At first I first thought that all we needed was to add semantics 
to take the address of a UFCS-style call, but after messing 
around with your example I realized that delegates are not 
ABI-compatible with functions that take the delegate ptr as the 
first parameter.  You mentioned that the problem was with the 
parameter order and that this should work with extern(C) 
functions and I think you're right.

The new DIP proposes the addition of "Extension Methods" which 
are functions that are ABI-compatible with delegates. You define 
an extension method by naming the first parameter "this":

struct Foo
{
     void bar(int x)
     {
     }
}
void baz(ref Foo this, int x)
{
}

Because the first parameter of baz is named this, it is an 
"extension method" of Foo which means it is ABI-compatible with 
the method bar.

void delegate(int x) dg;
Foo foo;

dg = &foo.bar;  // a normal method delegate
dg(42);         // calls foo.bar(42)

dg = &foo.baz;  // an extension method delegate
dg(42);         // calls baz(foo, 42);

dg = &baz;      // a "null delegate", unsafe code, funcptr points 
to the baz function, but ptr is null
dg(42);         // calls baz(null, 42);




More information about the Digitalmars-d mailing list