www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - UFCS and delegates

reply "Steve Teale" <steve.teale britseyeview.com> writes:
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);
}
Mar 15 2014
next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"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.
Mar 15 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
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
Mar 15 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"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.
Mar 15 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
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
Mar 15 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"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.
Mar 15 2014
parent "Steve Teale" <steve.teale britseyeview.com> writes:
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.
Mar 15 2014
prev sibling parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
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.
Mar 15 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
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.
Mar 15 2014
parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
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.
Mar 15 2014