<div dir="ltr">So from my dconf talk, I detailed a nasty hack to handle member function pointers in D.<div>My approach is not portable, so I'd like to see an expression formalised in D, so this sort of interaction with C++ is possible, and also it may be useful in D code directly.<div>
<br></div><div style>I'm thinking something like this... Keen to hear thoughts.</div></div><div style><br></div><div style>My approach was this:</div><div style>  void function(T _this, ...args...);<br></div><div style>
<br></div><div style>Explicit 'this' pointer; only works with ABI's that pass 'this' as the first integer argument.<br></div><div style><br></div><div style>What I suggest is:<br></div><div style>  void function(T this, ...args...);<br>
</div><div style><br></div><div style>Note, I use keyword 'this' as the first argument. This is the key that distinguishes the expression as a member-function pointer rather than a typical function pointer. Calls through this function pointer would know to use the method calling convention rather than the static function calling convention.</div>
<div style><br></div><div style>For 'extern(C++) void function(T this)', that would be to use the C++ 'thiscall' convention.</div><div style><br></div><div style>I think this makes good sense, because other than the choice of calling convention, it really is just a 'function' in every other way.<br>
</div><div style><br></div><div style>Now taken this as a declaration syntax, I think calls would be made via UFCS.</div><div style><br></div><div>T x;</div><div style>void function(T this) mp;<br></div><div style><br></div>
<div style>mp(x); // I guess this is fine<br></div><div style><a href="http://x.mp">x.mp</a>(); // but UFCS really makes this concept nice!</div><div style><br></div><div style>So the final detail, is how to capture one of these member function pointers from within D...</div>
<div style>I initially thought about a syntax, but this is so niche, I don't think it warrants a syntax.</div><div style>So my current best idea is to introduce 2 properties to delegates, so that the function pointer (of this type) can be accessed via the delegate syntax.</div>
<div style><br></div><div style>delegate d = &x.f;</div><div style>void function(T this) mp = d.funcPtr;</div><div style><br></div><div style>An interesting side effect, is that 'delegate' could actually be understood as a strongly-typed small struct, whereas currently, it's just a magic thing:</div>
<div style><br></div><div style>Given: RT delegate(A x, B y) d = &c.m;</div><div style><br></div><div style>It would look like:</div><div style>struct delegate(C)</div><div style>{</div><div style>  C thisPointer;</div>
<div style>  RT function(C this, A x, B, y) funcPointer;</div><div style>}</div><div style><br></div><div style>Currently, to get the instance or function pointers from a delegate, you need to do something like:</div><div style>
delegate d;</div><div style>void** pd = cast(void**)&d;</div><div style>T instancePointer = cast(T)pd[0];</div><div style>void function(T this) functionPointer = cast(RT function(T this))pd[1];</div><div style><br></div>
<div style>Casting through a void array like that is pretty horrible.</div><div style>Adding 2 properties to delegate to get either of those things can makes sense once it is possible to express the type of the function pointer, which would now be possible with the syntax above.</div>
<div style><br></div><div style>So, I quite like the transparency introduced when a delegate can be explicitly described in the language. But there is one loose detail...</div><div style><br></div><div style>void f()</div>
<div style>{</div><div style>  void g() {}</div><div style>  void delegate() d = &g; // delegate 'this' is a closure<br></div><div style>}</div><div style><br></div><div style>I don't know a syntax to describe the type of a closure, so when a delegate is typed with a closure instead of a struct/class, what is 'C' in the struct template above?</div>
<div style><br></div><div style><br></div><div style>Thoughts?</div><div style>Is there reason to outright ban this sort of expression?</div><div style>I think this actually clarifies some details of the language, and reduces a currently 'magic' thing into a well-defined, strongly-typed concept.</div>
<div style><br></div><div style>- Manu</div></div>