Address of UFCS call implicity converts to Delegate

Jonathan Marler via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 24 13:36:26 PDT 2017


On Monday, 24 April 2017 at 19:19:27 UTC, Meta wrote:
> On Monday, 24 April 2017 at 15:47:14 UTC, Jonathan Marler wrote:
>> 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);
>
> One small tweak is that `this` should act as a storage class 
> instead of the user having to name the parameter `this`. This 
> is what C# does so we should mimic it to avoid confusion.
>
> https://www.codeproject.com/Tips/709310/Extension-Method-In-Csharp

Yes I'm familiar with C# extension methods and that was my 
initial thought. The one advantage I saw with naming the 
parameter "this" was that it produces more "refactorable" code.  
If the first parameter of a delegateable function is a reference 
to a struct or a class, then you could move the function inside 
the struct/class, take out the first parameter and the code will 
work as a member function with no changes since the "this" 
keyword will be referring to the same object in both cases.  But 
it's not a big deal, either syntax works fine in my opinion.


More information about the Digitalmars-d mailing list