June 10, 2013
On Monday, 10 June 2013 at 12:53:34 UTC, Jacob Carlborg wrote:
> On 2013-06-10 14:36, Manu wrote:
>> funcptr pretends to be typed, but the type is just wrong. In your
>> example, the type is 'void function()', it should be 'void function(Foo
>> this)'.
>
> "void function()" is part of the complete type. It becomes complete with the context pointer.

I wouldn't say so. The fact that you pass context has nothing to do with determining type. For example, you can pass A class instead of B to B method, but B method would still keep its original type.

So yes, there is a type problem in language when function taking some parameter is declared as having no such parameter. This is a serious hole in type system.

June 10, 2013
On 10 June 2013 22:53, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 14:36, Manu wrote:
>
>  You supply 'this' at the time of calling. Read my OP.
>>
>
> Yes, exactly. It needs "this". It's the same thing as a delegate. It's
> just that with the delegate the context pointer and function pointer is
> combined. A function pointer (member or free) is useless if it's not called.
>
>
>  It's Don's work of art. It's also how I came to find out about D in the
>> first place ;)
>>
>
> I see.
>
>
>  There's no way to specify to use the 'thiscall' calling convention.
>> What I propose is a syntax that would describe a member function pointer, and imply the appropriate calling convention.
>>
>
> Right. I suggested a different syntax, but you want to reserve that syntax for something that match a library implementation, that's not even in the standard.
>
> It's like saying I want int[] to match MyIntArray implemented in C++.


No, I'm not talking about delegates. I'm not talking about FastDelegate (that was an aside when you commented that C++ has no concept of delegate). I'm just talking about function pointers. Not sure where you get this analogy from?

 funcptr pretends to be typed, but the type is just wrong. In your
>> example, the type is 'void function()', it should be 'void function(Foo
>> this)'.
>>
>
> "void function()" is part of the complete type. It becomes complete with
> the context pointer.


The context pointer type is not present in the type. So the function can't
be used/called.
It also doesn't know how to call it. What's the calling convention for
'void function()'? cdecl?

 So it's actually a lie. You can't call it. I'm not sure why it's typed
>> at all... just a crash waiting to happen.
>>
>
> You can put a free function in a delegate and call it through the delegate. I guess you don't want that to be possible either.


A free function? Like a static function? You can assign it, but it'll
crash. Free functions are cdecl, methods are thiscall.
If you know the ABI and it receives 'this' as the first integer argument,
you can fabricate a compatible signature and it won't crash, but it's not
portable.
This is my whole point about the type-safety. If we create an expression to
describe a method pointer, then we can actually do it safely and portably.

 So what I'm suggesting is a syntax to express a member function pointer,
>> and then it could be properly typed.
>>
>
> I don't think there's anything wrong with supporting C++ member function pointers but I don't think we need to add new syntax for it.


I'm not suggesting supporting 'C++ member function pointers', they are
completely bat-shit crazy.
I'm suggesting a distinctly D way. They will be useful when interfacing
C++, and also on their own, and unlike C++, they won't be totally mental.


June 10, 2013
On Friday, 7 June 2013 at 23:22:03 UTC, Manu wrote:
> I think this makes good sense, because other than the choice of calling
> convention, it really is just a 'function' in every other way.

Another less intrusive option would be to just add extern(CppThisCall) and extern(DThisCall) or something along the lines, which would be specified to pass the first parameter as if it was a this pointer.

David
June 10, 2013
On 10 June 2013 22:56, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 14:32, Michel Fortin wrote:
>
>  Type-safety. I mean, you can do this if you want:
>>
>>      auto funcptr = &Object.toString;
>>      auto object = new Object;
>>
>>      // now call our function using object
>>      string delegate() deleg;
>>      deleg.ptr = cast(void*)object;
>>      deleg.funcptr = funcptr;
>>
>> but this is not type-safe: the funcptr type ("string function()") is actually wrong (it'll only work if called from a delegate) and the object pointer the in the delegate is a void*. All Manu is asking is that funcptr is of a correct type so you can call it directly by supplying "this" as an argument, like this:
>>
>>      funcptr(object);
>>
>> The problem is that this "correct type" for the function pointer does not exist currently. Calling a member function uses a different ABI, so the type needs to know somehow its a pointer to a member function (and that its first parameter is "this"), otherwise the generated code at the call site will be all wrong.
>>
>
> Then he's asking for (more) type safe delegates and support for C++ member
> function pointers.


I'm really not asking for delegates (although they could become more typesafe given my suggestion), just a member function pointer. And not C++ style as you say, my suggestion is much simpler than that, and would fit nicely in D.


June 10, 2013
On Monday, 10 June 2013 at 13:45:37 UTC, Manu wrote:
> What's the calling convention for
> 'void function()'? cdecl?

Walter's very own calling convention. It is supposed to match cdecl everywhere but x86, but has the argument order reversed. On x86, it's a custom one that's similar to stdcall in some ways.

David
June 10, 2013
On 10 June 2013 23:46, David Nadlinger <code@klickverbot.at> wrote:

> On Friday, 7 June 2013 at 23:22:03 UTC, Manu wrote:
>
>> I think this makes good sense, because other than the choice of calling convention, it really is just a 'function' in every other way.
>>
>
> Another less intrusive option would be to just add extern(CppThisCall) and extern(DThisCall) or something along the lines, which would be specified to pass the first parameter as if it was a this pointer.


That would also do the business. Do you think that's less intrusive?
It feels a little hacky though. 'DThisCall' isn't really 'extern' so to
speak.
I like my suggestion a lot more. Little details like, what would you name
the 'this' argument? You'll end up with conventions like 'void function(T
_this)', and that's a bit untrue because there isn't an argument named
'_this', it's called 'this' inside the method.


June 10, 2013
On 10 June 2013 23:49, David Nadlinger <code@klickverbot.at> wrote:

> On Monday, 10 June 2013 at 13:45:37 UTC, Manu wrote:
>
>> What's the calling convention for
>> 'void function()'? cdecl?
>>
>
> Walter's very own calling convention. It is supposed to match cdecl everywhere but x86, but has the argument order reversed. On x86, it's a custom one that's similar to stdcall in some ways.


Indeed. I presume 'extern(C) void function()' is cdecl though?
Likewise 'extern(C++) void function(T this)' would be 'thiscall', and 'void
function(T this)' would be whatever D's method calling convention happens
to be.


June 10, 2013
On Monday, 10 June 2013 at 14:04:29 UTC, Manu wrote:
> On 10 June 2013 23:46, David Nadlinger <code@klickverbot.at>
>> Another less intrusive option would be to just add extern(CppThisCall) and
>> extern(DThisCall) or something along the lines, which would be specified to
>> pass the first parameter as if it was a this pointer.
>
>
> That would also do the business. Do you think that's less intrusive?

Less intrusive in the way that it is a minimal addition to the language itself (we already have several calling conventions), whereas your suggestion would require adding a special case to the grammar.

That's not to say I don't like your proposal, though. I just wanted to put the option on the table to be sure we are getting somewhere with this, even if some people might be opposed to the grammar change. This issue has been bugging me for quite some time as well.

> It feels a little hacky though. 'DThisCall' isn't really 'extern' so to speak.

extern(D) exists today – extern(xyz) should really be called abi(xyz), callingconv(xyz) or something like that instead.

David
June 10, 2013
On 2013-06-10 14:11:31 +0000, "David Nadlinger" <code@klickverbot.at> said:

> On Monday, 10 June 2013 at 14:04:29 UTC, Manu wrote:
>> On 10 June 2013 23:46, David Nadlinger <code@klickverbot.at>
>>> Another less intrusive option would be to just add extern(CppThisCall) and
>>> extern(DThisCall) or something along the lines, which would be specified to
>>> pass the first parameter as if it was a this pointer.
>> 
>> That would also do the business. Do you think that's less intrusive?
> 
> Less intrusive in the way that it is a minimal addition to the language itself (we already have several calling conventions), whereas your suggestion would require adding a special case to the grammar.
> 
> That's not to say I don't like your proposal, though. I just wanted to put the option on the table to be sure we are getting somewhere with this, even if some people might be opposed to the grammar change. This issue has been bugging me for quite some time as well.

It's inelegant, but it could work.

I just find it sad that we have to use a different calling convention for member functions. I mean, it'd be much more elegant be if a member function could simply be called from a "void function(Object)" by supplying "this" as the first argument? Wouldn't it be better to adapt the ABI to fit the language rather than adapt the language to fit the ABI?

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca/

June 10, 2013
On 11 June 2013 00:28, Michel Fortin <michel.fortin@michelf.ca> wrote:

> On 2013-06-10 14:11:31 +0000, "David Nadlinger" <code@klickverbot.at> said:
>
>  On Monday, 10 June 2013 at 14:04:29 UTC, Manu wrote:
>>
>>> On 10 June 2013 23:46, David Nadlinger <code@klickverbot.at>
>>>
>>>> Another less intrusive option would be to just add extern(CppThisCall)
>>>> and
>>>> extern(DThisCall) or something along the lines, which would be
>>>> specified to
>>>> pass the first parameter as if it was a this pointer.
>>>>
>>>
>>> That would also do the business. Do you think that's less intrusive?
>>>
>>
>> Less intrusive in the way that it is a minimal addition to the language itself (we already have several calling conventions), whereas your suggestion would require adding a special case to the grammar.
>>
>> That's not to say I don't like your proposal, though. I just wanted to put the option on the table to be sure we are getting somewhere with this, even if some people might be opposed to the grammar change. This issue has been bugging me for quite some time as well.
>>
>
> It's inelegant, but it could work.
>
> I just find it sad that we have to use a different calling convention for member functions. I mean, it'd be much more elegant be if a member function could simply be called from a "void function(Object)" by supplying "this" as the first argument? Wouldn't it be better to adapt the ABI to fit the language rather than adapt the language to fit the ABI?


The ABI is the better part of half a century old...