Member function pointers

Manu turkeyman at gmail.com
Fri Jun 7 16:21:53 PDT 2013


So from my dconf talk, I detailed a nasty hack to handle member function
pointers in D.
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.

I'm thinking something like this... Keen to hear thoughts.

My approach was this:
  void function(T _this, ...args...);

Explicit 'this' pointer; only works with ABI's that pass 'this' as the
first integer argument.

What I suggest is:
  void function(T this, ...args...);

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.

For 'extern(C++) void function(T this)', that would be to use the C++
'thiscall' convention.

I think this makes good sense, because other than the choice of calling
convention, it really is just a 'function' in every other way.

Now taken this as a declaration syntax, I think calls would be made via
UFCS.

T x;
void function(T this) mp;

mp(x); // I guess this is fine
x.mp(); // but UFCS really makes this concept nice!

So the final detail, is how to capture one of these member function
pointers from within D...
I initially thought about a syntax, but this is so niche, I don't think it
warrants a syntax.
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.

delegate d = &x.f;
void function(T this) mp = d.funcPtr;

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:

Given: RT delegate(A x, B y) d = &c.m;

It would look like:
struct delegate(C)
{
  C thisPointer;
  RT function(C this, A x, B, y) funcPointer;
}

Currently, to get the instance or function pointers from a delegate, you
need to do something like:
delegate d;
void** pd = cast(void**)&d;
T instancePointer = cast(T)pd[0];
void function(T this) functionPointer = cast(RT function(T this))pd[1];

Casting through a void array like that is pretty horrible.
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.

So, I quite like the transparency introduced when a delegate can be
explicitly described in the language. But there is one loose detail...

void f()
{
  void g() {}
  void delegate() d = &g; // delegate 'this' is a closure
}

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?


Thoughts?
Is there reason to outright ban this sort of expression?
I think this actually clarifies some details of the language, and reduces a
currently 'magic' thing into a well-defined, strongly-typed concept.

- Manu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130608/b87a3b6b/attachment.html>


More information about the Digitalmars-d mailing list