Jump to page: 1 2 3
Thread overview
why can't structs implement interfaces?
Nov 24, 2009
Saaa
Nov 24, 2009
Moritz Warning
Nov 24, 2009
bearophile
Nov 24, 2009
Saaa
Nov 24, 2009
Bill Baxter
Nov 24, 2009
Lutger
Nov 24, 2009
Saaa
Nov 24, 2009
Bill Baxter
Nov 25, 2009
Daniel Keep
Nov 25, 2009
Bill Baxter
Nov 25, 2009
Saaa
Nov 25, 2009
bearophile
Nov 24, 2009
Bill Baxter
Nov 25, 2009
bearophile
Nov 25, 2009
Don
Nov 25, 2009
bearophile
Nov 25, 2009
bearophile
Nov 25, 2009
Don
Nov 25, 2009
bearophile
Nov 24, 2009
Lutger
Nov 25, 2009
Rory McGuire
Nov 25, 2009
wakko
November 24, 2009
struct S : Pos {}
Why is this not possible?


November 24, 2009
On Tue, 24 Nov 2009 21:55:02 +0100, Saaa wrote:

> struct S : Pos {}
> Why is this not possible?

The struct would need an additional pointer
for a dispatch table in case you want to have class semantics.

If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
November 24, 2009
Moritz Warning:

> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.

In the meantime this can be done with a template mixin, where the template statically asserts the presence of the functions/fields you want.

Bye,
bearophile
November 24, 2009
Saaa wrote:

> struct S : Pos {}
> Why is this not possible?
> 
> 

Because structs are meant to be value types and thus do not implement dynamic polymorphism, which is what interfaces are used for.  It is not necessary though, classes in C++ are almost the same as structs for example, but there are problems with that design.


November 24, 2009
bearophile wrote:
> Moritz Warning:
>
>> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
>
> In the meantime this can be done with a template mixin, where the template statically asserts the presence of the functions/fields you want.
>
> Bye,
> bearophile

I wanted to do something like this:

class C : I {};
struct S : I {};
S s;
I[] i =[new C(), s ];


November 24, 2009
On Tue, Nov 24, 2009 at 2:49 PM, Saaa <empty@needmail.com> wrote:
> bearophile wrote:
>> Moritz Warning:
>>
>>> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
>>
>> In the meantime this can be done with a template mixin, where the template statically asserts the presence of the functions/fields you want.
>>
>> Bye,
>> bearophile
>
> I wanted to do something like this:
>
> class C : I {};
> struct S : I {};
> S s;
> I[] i =[new C(), s ];

Yeh, that's never going to work because that's acting as a dynamic polymorphic interaface.  Referring polymorphically to a struct like that pretty much makes it not a struct anymore, and requires having the hidden pointer to a vtable that was mentioned.  That's what classes are for.

In D2 you can use "alias this" inside a class to forward things to the struct, though. Something like this:

class ClassWrapper(S) : I {
   S _impl;
   alias _impl this;
}

But I somehow doubt DMD will consider methods handled by S as being an
implementation of the interface.
So you'll need explicit forwarding.

--bb
November 24, 2009
Bill Baxter wrote:

> On Tue, Nov 24, 2009 at 2:49 PM, Saaa <empty@needmail.com> wrote:
>> bearophile wrote:
>>> Moritz Warning:
>>>
>>>> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
>>>
>>> In the meantime this can be done with a template mixin, where the template statically asserts the presence of the functions/fields you want.
>>>
>>> Bye,
>>> bearophile
>>
>> I wanted to do something like this:
>>
>> class C : I {};
>> struct S : I {};
>> S s;
>> I[] i =[new C(), s ];
> 
> Yeh, that's never going to work because that's acting as a dynamic polymorphic interaface.  Referring polymorphically to a struct like that pretty much makes it not a struct anymore, and requires having the hidden pointer to a vtable that was mentioned.  That's what classes are for.
> 
> In D2 you can use "alias this" inside a class to forward things to the struct, though. Something like this:
> 
> class ClassWrapper(S) : I {
>    S _impl;
>    alias _impl this;
> }
> 
> But I somehow doubt DMD will consider methods handled by S as being an
> implementation of the interface.
> So you'll need explicit forwarding.
> 
> --bb

I can confirm that it is not possible with alias this.

Somewhat related, template mixins can add virtual methods:

template T() { /*implementation of I*/ }
class C : I  { mixin T!(); } // adds methods in T!() as virtual methods





November 24, 2009
Bill Baxter wrote:
> On Tue, Nov 24, 2009 at 2:49 PM, Saaa <empty@needmail.com> wrote:
>> bearophile wrote:
>>> Moritz Warning:
>>>
>>>> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
>>>
>>> In the meantime this can be done with a template mixin, where the
>>> template
>>> statically asserts the presence of the functions/fields you want.
>>>
>>> Bye,
>>> bearophile
>>
>> I wanted to do something like this:
>>
>> class C : I {};
>> struct S : I {};
>> S s;
>> I[] i =[new C(), s ];
>
> Yeh, that's never going to work because that's acting as a dynamic polymorphic interaface.  Referring polymorphically to a struct like that pretty much makes it not a struct anymore, and requires having the hidden pointer to a vtable that was mentioned.  That's what classes are for.
Why is a hidden pointer necessary? (Just curious :)

My simplistic view was like this:
i[1] would just hold the location of s and s would be checked to have
all it needs to be an I.

>
> In D2 you can use "alias this" inside a class to forward things to the struct, though. Something like this:
>
> class ClassWrapper(S) : I {
>   S _impl;
>   alias _impl this;
> }
>
> But I somehow doubt DMD will consider methods handled by S as being an
> implementation of the interface.
> So you'll need explicit forwarding.
>
> --bb


November 24, 2009
On Tue, Nov 24, 2009 at 3:09 PM, Saaa <empty@needmail.com> wrote:

>>> I wanted to do something like this:
>>>
>>> class C : I {};
>>> struct S : I {};
>>> S s;
>>> I[] i =[new C(), s ];
>>
>> Yeh, that's never going to work because that's acting as a dynamic polymorphic interaface.  Referring polymorphically to a struct like that pretty much makes it not a struct anymore, and requires having the hidden pointer to a vtable that was mentioned.  That's what classes are for.
> Why is a hidden pointer necessary? (Just curious :)
>
> My simplistic view was like this:
> i[1] would just hold the location of s and s would be checked to have
> all it needs to be an I.

I think it could be done with a different implementation of interfaces
from the one D uses, one based on "fat pointers".
With that design an I referring to an S would be a "fat pointer", one
pointer pointing to the S and one pointing to S's table of function
pointers (vtable) for the I interface.

That's not how D does it AFAIR, but I don't actually recall how D does it.

--bb
November 24, 2009
On Tue, Nov 24, 2009 at 2:36 PM, bearophile <bearophileHUGS@lycos.com> wrote:
> Moritz Warning:
>
>> If you only what a contract that certain functions are implemented, then it just need to be implemented in the compiler frontend.
>
> In the meantime this can be done with a template mixin, where the template statically asserts the presence of the functions/fields you want.

I really think some kind of static interface (concept) support is
going to be necessary eventually.

In terms of functionality, static asserts and "isInterfaceSupported()"
methods are OK.  But the usability is not great.
In particular there's not a good way for the compiler to give good
error messages about why a concept is not satisfied by a particular
type.  I tried to come up with a way to do that given access to
compiler error messages, but the result looks rather like attempts to
do runtime inheritance in C.
The good thing is that since most of the machinery is there, the
actual compiler changes required would mostly be just rewrites of new
syntax in terms of existing functionality.

--bb
« First   ‹ Prev
1 2 3