View mode: basic / threaded / horizontal-split · Log in · Help
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
"Mehrdad" <wfunction@hotmail.com> wrote in message 
news:ifswigmcenyryxzyvbpv@forum.dlang.org...
> On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:
>> On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu 
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> On 5/18/12 1:22 PM, Mehrdad wrote:
>>>> My brain just exploded.
>>>> Can someone explain what's going on?
>>>>
>>>> class Test
>>>> {
>>>> public void foo() { }
>>>> }
>>>>
>>>> static assert(is(typeof(&Test.foo) == void function()));
>>>
>>> Looks like a bug. The assert should pass only if foo were static.
>>
>> No, this is not a bug.
>>
>> The purpose is so you can get the function pointer portion of a delegate 
>> without an instance of the object.
>
> I actually realized that might be the reason before I reported this, but 
> then I thought:
>
> In that case, shouldn't the 'this' parameter be explicitly part of the 
> function (at the end of the parameter list)?

No, that won't work in all cases due to the ordering of parameters, 'this' 
and the hidden struct pointer.
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On Saturday, 19 May 2012 at 01:37:54 UTC, Daniel Murphy wrote:
> No, that won't work in all cases due to the ordering of 
> parameters, 'this' and the hidden struct pointer.

Better than not working in /any/ cases lol. :P

Maybe you can add a void* for the hidden struct parameter? idk...
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
"Mehrdad" <wfunction@hotmail.com> wrote in message 
news:sxiwbwuwvcjrlvpfsgpi@forum.dlang.org...
> On Saturday, 19 May 2012 at 01:37:54 UTC, Daniel Murphy wrote:
>> No, that won't work in all cases due to the ordering of parameters, 
>> 'this' and the hidden struct pointer.
>
> Better than not working in /any/ cases lol. :P
>
> Maybe you can add a void* for the hidden struct parameter? idk...

I'd actually rather it /didn't/ work in any cases, and just returned void*. 
The .funcptr property of delegates too.  From what I can tell the main use 
of this 'feature' is to cause nasty bugs whenever somebody accidentally 
takes the address of a non-static member function without an instance.
Last time I checked, phobos uses this in a couple of places to see if a 
member function can be called with a specific set of args, but this can be 
replaced with S.init.func(...).  There is an existing bug report for this 
somewhere.
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On Saturday, 19 May 2012 at 02:38:11 UTC, Daniel Murphy wrote:
> I'd actually rather it /didn't/ work in any cases, and just 
> returned void*.

Well if that's an option then I like that too.
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
Le 19/05/2012 03:37, Daniel Murphy a écrit :
> "Mehrdad"<wfunction@hotmail.com>  wrote in message
> news:ifswigmcenyryxzyvbpv@forum.dlang.org...
>> On Friday, 18 May 2012 at 18:59:23 UTC, Steven Schveighoffer wrote:
>>> On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu
>>> <SeeWebsiteForEmail@erdani.org>  wrote:
>>>
>>>> On 5/18/12 1:22 PM, Mehrdad wrote:
>>>>> My brain just exploded.
>>>>> Can someone explain what's going on?
>>>>>
>>>>> class Test
>>>>> {
>>>>> public void foo() { }
>>>>> }
>>>>>
>>>>> static assert(is(typeof(&Test.foo) == void function()));
>>>>
>>>> Looks like a bug. The assert should pass only if foo were static.
>>>
>>> No, this is not a bug.
>>>
>>> The purpose is so you can get the function pointer portion of a delegate
>>> without an instance of the object.
>>
>> I actually realized that might be the reason before I reported this, but
>> then I thought:
>>
>> In that case, shouldn't the 'this' parameter be explicitly part of the
>> function (at the end of the parameter list)?
>
> No, that won't work in all cases due to the ordering of parameters, 'this'
> and the hidden struct pointer.
>
>

extern(this) and you are done expressing thiscall.
May 19, 2012
Re: Method pointers are *function* pointers?? Or delegates??
Le 18/05/2012 22:35, Andrei Alexandrescu a écrit :
> On 5/18/12 1:59 PM, Steven Schveighoffer wrote:
>> On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> On 5/18/12 1:22 PM, Mehrdad wrote:
>>>> My brain just exploded.
>>>> Can someone explain what's going on?
>>>>
>>>> class Test
>>>> {
>>>> public void foo() { }
>>>> }
>>>>
>>>> static assert(is(typeof(&Test.foo) == void function()));
>>>
>>> Looks like a bug. The assert should pass only if foo were static.
>>
>> No, this is not a bug.
>
> It is.
>
>> The purpose is so you can get the function pointer portion of a delegate
>> without an instance of the object.
>
> Typing is what it is. The following program is unsound without a cast in
> sight:
>
> class Test
> {
> void foo() { writeln("foo"); }
> }
>
> static assert(is(typeof(&Test.foo) == void function()));
>
> void fun()
> {
> writeln("fun");
> }
>
> void main() {
> alias void function() TFun;
> TFun a = &fun;
> a();
> a = &Test.foo;
> a();
> }
>
> At best things could be arranged that &Test.foo has type void
> function(Test) or something.
>
>
> Andrei

It would be nice, but require a way to express that calling convention 
(thiscall is often different than simply passing an argument).

I proposed extern(this).

This would have the extra benefice of being able to declare UFCS with 
thiscall convention.

If the extern isn't added, the feature must go, it is made to write bugs.
May 22, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On Fri, 18 May 2012 16:35:38 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail@erdani.org> wrote:

> On 5/18/12 1:59 PM, Steven Schveighoffer wrote:
>> On Fri, 18 May 2012 14:30:46 -0400, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> On 5/18/12 1:22 PM, Mehrdad wrote:
>>>> My brain just exploded.
>>>> Can someone explain what's going on?
>>>>
>>>> class Test
>>>> {
>>>> public void foo() { }
>>>> }
>>>>
>>>> static assert(is(typeof(&Test.foo) == void function()));
>>>
>>> Looks like a bug. The assert should pass only if foo were static.
>>
>> No, this is not a bug.
>
> It is.

Poor design?  Yes.  Bug? no.  It's behavior is very intentional and has  
been discussed several times over the last several years.  It's existed  
before D2 was even branched, at least since I learned D in 2007.

>> The purpose is so you can get the function pointer portion of a delegate
>> without an instance of the object.
>
> Typing is what it is. The following program is unsound without a cast in  
> sight:
>
> class Test
> {
>      void foo() { writeln("foo"); }
> }
>
> static assert(is(typeof(&Test.foo) == void function()));
>
> void fun()
> {
>      writeln("fun");
> }
>
> void main() {
>      alias void function() TFun;
>      TFun a = &fun;
>      a();
>      a = &Test.foo;
>      a();
> }

I agree, it's unsound.  But so is this:

int *blah = void;

*blah = 5;

It doesn't mean that the language should forbid it, or that the compiler  
isn't implemented as designed.

At the *very least*, the address to member function operation should be  
illegal in @safe code.

> At best things could be arranged that &Test.foo has type void  
> function(Test) or something.

I would suggest that it should be:

function(Test this) with the 'this' being mangled into the name, and  
affect the calling convention.

Structs would be function(ref Test this).

And const/shared/immutable decorations should apply properly to the 'this'  
parameter.

I'd wholeheartedly support such an improvement.  In fact, I'd be willing  
to write a DIP on it, if Walter had a chance of approving it.  I just  
don't know if it would happen...

-Steve
May 22, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On 2012-05-22 20:14, Steven Schveighoffer wrote:

> I agree, it's unsound. But so is this:
>
> int *blah = void;
>
> *blah = 5;
>
> It doesn't mean that the language should forbid it, or that the compiler
> isn't implemented as designed.
>
> At the *very least*, the address to member function operation should be
> illegal in @safe code.
>
>> At best things could be arranged that &Test.foo has type void
>> function(Test) or something.
>
> I would suggest that it should be:
>
> function(Test this) with the 'this' being mangled into the name, and
> affect the calling convention.
>
> Structs would be function(ref Test this).
>
> And const/shared/immutable decorations should apply properly to the
> 'this' parameter.
>
> I'd wholeheartedly support such an improvement. In fact, I'd be willing
> to write a DIP on it, if Walter had a chance of approving it. I just
> don't know if it would happen...
>
> -Steve

It needs to be possible to compose delegates:

class Foo
{
    void foo () {};
}

void delegate () dg;

dg.funcptr = &Foo.foo;
dg.ptr = cast(void*) new Foo;
dg();

At least it needs to be possible to do that in code marked with @system.

-- 
/Jacob Carlborg
May 22, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On Tue, 22 May 2012 14:28:33 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2012-05-22 20:14, Steven Schveighoffer wrote:
>
>> I would suggest that it should be:
>>
>> function(Test this) with the 'this' being mangled into the name, and
>> affect the calling convention.
>>
>> Structs would be function(ref Test this).
>>
>> And const/shared/immutable decorations should apply properly to the
>> 'this' parameter.
>>
>> I'd wholeheartedly support such an improvement. In fact, I'd be willing
>> to write a DIP on it, if Walter had a chance of approving it. I just
>> don't know if it would happen...
>>
>
> It needs to be possible to compose delegates:
>
> class Foo
> {
>      void foo () {};
> }
>
> void delegate () dg;
>
> dg.funcptr = &Foo.foo;

Error, cannot cast function of type void function(Foo this) to void  
function(void *this)

dg.funcptr = cast(void function(void *this))&Foo.foo; // ok

> dg.ptr = cast(void*) new Foo;
> dg();
>
> At least it needs to be possible to do that in code marked with @system.
>

I think it should require a cast, regardless of the @system attribute, you  
are telling the type system a function that requires a Foo is now OK to  
accept a void *.  I don't think that's something we should accept  
implicitly.

-Steve
May 22, 2012
Re: Method pointers are *function* pointers?? Or delegates??
On 2012-05-22 20:35, Steven Schveighoffer wrote:

>> It needs to be possible to compose delegates:
>>
>> class Foo
>> {
>> void foo () {};
>> }
>>
>> void delegate () dg;
>>
>> dg.funcptr = &Foo.foo;
>
> Error, cannot cast function of type void function(Foo this) to void
> function(void *this)
>
> dg.funcptr = cast(void function(void *this))&Foo.foo; // ok
>
>> dg.ptr = cast(void*) new Foo;
>> dg();
>>
>> At least it needs to be possible to do that in code marked with @system.
>>
>
> I think it should require a cast, regardless of the @system attribute,
> you are telling the type system a function that requires a Foo is now OK
> to accept a void *. I don't think that's something we should accept
> implicitly.
>
> -Steve

I have no problem with a couple of case, as long as it's possible to 
compose delegates as above. The example was just how it works today, and 
an explanation of what I meant by "composing delegates". This can be of 
great help when interfacing with other language. I used this technique 
to call D methods from Objective-C.

-- 
/Jacob Carlborg
1 2 3
Top | Discussion index | About this forum | D home