Thread overview
UFCS and delegates
Mar 15, 2014
Steve Teale
Mar 15, 2014
Daniel Murphy
Mar 15, 2014
Steve Teale
Mar 15, 2014
Daniel Murphy
Mar 15, 2014
Steve Teale
Mar 15, 2014
Daniel Murphy
Mar 15, 2014
Steve Teale
Mar 15, 2014
Rikki Cattermole
Mar 15, 2014
Steve Teale
Mar 15, 2014
Rikki Cattermole
March 15, 2014
Doesn't the logic of UFCS rather suggest that this should compile?

struct A
{
   int m;
   void foo(int n) { m += n; }
}

void bar(ref A a, int n)
{
   a.foo(n*n);
}

void delegate(int) dg = &bar;

void main()
{
   A a;
   a.bar(3);
   dg(3);
   assert(a.m == 18);
}
March 15, 2014
"Steve Teale"  wrote in message news:dtevbsedsbbvqhaiefvi@forum.dlang.org...

> Doesn't the logic of UFCS rather suggest that this should compile?

Nope, UFCS is a rewrite rule, it doesn't change function signatures. 

March 15, 2014
On Saturday, 15 March 2014 at 08:33:13 UTC, Steve Teale wrote:
> Doesn't the logic of UFCS rather suggest that this should compile?
>
> struct A
> {
>    int m;
>    void foo(int n) { m += n; }
> }
>
> void bar(ref A a, int n)
> {
>    a.foo(n*n);
> }
>
> void delegate(int) dg = &bar;
>
> void main()
> {
>    A a;
>    a.bar(3);
>    dg(3);
>    assert(a.m == 18);
> }

This yes:

struct A
{
    int m;
    void foo(int n) { m += n; }
	
    void bar(int n) {
       foo(n*n);
    }

}

void main()
{
    A a;
    void delegate(int) dg = &a.bar;

    a.bar(3);
    dg(3);
    assert(a.m == 18);
}

yours no.
Because a delegate stores a context ptr aka this. As well as a function pointer. What you were doing meant that no content pointer was being stored. Essentially it was just a function pointer without the first argument added.
March 15, 2014
On Saturday, 15 March 2014 at 09:13:47 UTC, Rikki Cattermole wrote:

> yours no.
> Because a delegate stores a context ptr aka this. As well as a function pointer. What you were doing meant that no content pointer was being stored. Essentially it was just a function pointer without the first argument added.

Why isn't the first argument, removed in the rewrite, used as the context?

In cases where the type of the first argument was not suitable, the compiler could issue an error message.
March 15, 2014
On Saturday, 15 March 2014 at 09:09:23 UTC, Daniel Murphy wrote:
> "Steve Teale"  wrote in message news:dtevbsedsbbvqhaiefvi@forum.dlang.org...
>
>> Doesn't the logic of UFCS rather suggest that this should compile?
>
> Nope, UFCS is a rewrite rule, it doesn't change function signatures.

I was asking about the logic - as expounded in the discussions before its introduction, as opposed to the implementation rules adopted.

Steve
March 15, 2014
"Steve Teale"  wrote in message news:nnnhcikeieyqnaujpddr@forum.dlang.org...

> I was asking about the logic - as expounded in the discussions before its introduction, as opposed to the implementation rules adopted.

Yes, that's what I was talking about.  UFCS is and always has been a rewrite rule. 

March 15, 2014
On Saturday, 15 March 2014 at 09:41:18 UTC, Steve Teale wrote:
> On Saturday, 15 March 2014 at 09:13:47 UTC, Rikki Cattermole wrote:
>
>> yours no.
>> Because a delegate stores a context ptr aka this. As well as a function pointer. What you were doing meant that no content pointer was being stored. Essentially it was just a function pointer without the first argument added.
>
> Why isn't the first argument, removed in the rewrite, used as the context?
>
> In cases where the type of the first argument was not suitable, the compiler could issue an error message.

Because it must be explicit in nature when its created. You can have many delegates to the "same" method on a class/struct but they are different if the instances are not the same.
March 15, 2014
On Saturday, 15 March 2014 at 09:51:53 UTC, Daniel Murphy wrote:
>
> Yes, that's what I was talking about.  UFCS is and always has been a rewrite rule.

Yes, I'm asking for the wrong thing. What I should have said is that given UFCS, should there be an alternate way of initializing a delegate, something along the lines of:

void delegate(int) dg = (a, &bar);

Steve
March 15, 2014
"Steve Teale"  wrote in message news:uhledfeisciwpvtvmhbp@forum.dlang.org...

> Yes, I'm asking for the wrong thing. What I should have said is that given UFCS, should there be an alternate way of initializing a delegate, something along the lines of:
>
> void delegate(int) dg = (a, &bar);
>

Well, if you know the instance, you can do this:

void delegate(int) dg = (int v) { a.bar(v); }

But this would have to go inside main.

If you want to supply the instance later, then you could use toDelegate on 'bar' to get you a delegate, or write a wrapping delegate yourself, but it will naturally have two parameters. 

March 15, 2014
On Saturday, 15 March 2014 at 11:02:08 UTC, Daniel Murphy wrote:
> "Steve Teale"  wrote in message news:uhledfeisciwpvtvmhbp@forum.dlang.org...
>
>> Yes, I'm asking for the wrong thing. What I should have said is that given UFCS, should there be an alternate way of initializing a delegate, something along the lines of:
>>
>> void delegate(int) dg = (a, &bar);
>>
>
> Well, if you know the instance, you can do this:
>
> void delegate(int) dg = (int v) { a.bar(v); }
>
> But this would have to go inside main.

This seems a long way around the houses, is difficult to understand, and the result is a delegate with a frame pointer for the main function, which then has a nested function

void anon(int v) { a.bar(v); }

which somehow does not feel right, and if the compiler isn't clever, seems like another level of indirection.

Syntax like this (changed my mind ;=)) would be nice:

void delegate(int) dg = &a.bar;

I'm not particularly looking for a way of doing it at this moment, just whether it's something that could be done in the future.