Jump to page: 1 2
Thread overview
structs inheriting from and implementing interfaces
Dec 29
Seb
Dec 29
rjframe
Dec 29
Basile B.
Dec 29
Mengu
Jan 02
rjframe
Jan 02
Chris M.
Dec 29
thedeemon
Dec 29
Basile B.
Jan 02
Meta
December 29
In C#, structs can inherit from and implement interfaces.

----
using System;

interface IPrint
{
    void Print();
}

struct MyStruct : IPrint
{
    public void Print()
    {
        Console.WriteLine(ToString());
    }
}

public class Program
{
    public static void Main()
    {
        MyStruct s = new MyStruct();
        s.Print();
    }
}
----
https://dotnetfiddle.net/lpXR1O

But in D it doesn't appear possible.
----
import std.stdio;

interface IPrint
{
    void print();
}

// Error: base classes are not allowed for struct, did you mean ;?
struct MyStruct : IPrint   // Error: base classes are not allowed for struct, did you mean ;?
{
    void print()
    {
        writeln("MyStruct");
    }
}

void main()
{
	MyStruct s;
    s.Print();
}
----
https://run.dlang.io/is/j4xwla

Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?

Thanks for your insight,

Mike
December 29
On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> In C#, structs can inherit from and implement interfaces.
>
> ----
> using System;
>
> interface IPrint
> {
>     void Print();
> }
>
> struct MyStruct : IPrint
> {
>     public void Print()
>     {
>         Console.WriteLine(ToString());
>     }
> }
>
> public class Program
> {
>     public static void Main()
>     {
>         MyStruct s = new MyStruct();
>         s.Print();
>     }
> }
> ----
> https://dotnetfiddle.net/lpXR1O
>
> But in D it doesn't appear possible.
> ----
> import std.stdio;
>
> interface IPrint
> {
>     void print();
> }
>
> // Error: base classes are not allowed for struct, did you mean ;?
> struct MyStruct : IPrint   // Error: base classes are not allowed for struct, did you mean ;?
> {
>     void print()
>     {
>         writeln("MyStruct");
>     }
> }
>
> void main()
> {
> 	MyStruct s;
>     s.Print();
> }
> ----
> https://run.dlang.io/is/j4xwla
>
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?
>
> Thanks for your insight,
>
> Mike

I think it simply hasn't been implemented, but I am not sure here because you could simply insert a `static assert` in there (and probably have something like `hasInterface!(Interface, YourStruct)`. Similarly multiple `alias this` is a request that often comes up.
December 29
Structs are structs, classes are classes.

C++ had the mixed model similar to what you suggested, we got it right and kept it nice and separate. This was done on purpose.
December 29
On Friday, 29 December 2017 at 12:11:46 UTC, rikki cattermole wrote:
> Structs are structs, classes are classes.

I'm talking about interfaces, which are neither structs nor classes.

> C++ had the mixed model similar to what you suggested, we got it right and kept it nice and separate. This was done on purpose.

I'm comparing with C#, not C++.  And structs implementing interfaces does not blur the two concepts, as C# eloquently demonstrates.

Mike
December 29
On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> In C#, structs can inherit from and implement interfaces.
>
> ----
> using System;
>
> interface IPrint
> {
>     void Print();
> }
>
> struct MyStruct : IPrint
> {
>     public void Print()
>     {
>         Console.WriteLine(ToString());
>     }
> }
>
> public class Program
> {
>     public static void Main()
>     {
>         MyStruct s = new MyStruct();
>         s.Print();
>     }
> }
> ----
> https://dotnetfiddle.net/lpXR1O
>
> But in D it doesn't appear possible.
> ----
> import std.stdio;
>
> interface IPrint
> {
>     void print();
> }
>
> // Error: base classes are not allowed for struct, did you mean ;?
> struct MyStruct : IPrint   // Error: base classes are not allowed for struct, did you mean ;?
> {
>     void print()
>     {
>         writeln("MyStruct");
>     }
> }
>
> void main()
> {
> 	MyStruct s;
>     s.Print();
> }
> ----
> https://run.dlang.io/is/j4xwla
>
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?
>
> Thanks for your insight,
>
> Mike

The problem is that interfaces are a runtime thing (e.g. you can cast a class to an interface)
structs implement compile time interfaces via template duck typing (usually enforced via an if()).
you could probably write a wrapper that introspected an interface and enforced that all members were implemented.
December 29
On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?

It's a design decision.
Look carefully at structs vs. classes here:
https://dlang.org/spec/struct.html

There is no virtual methods table (VMT) for structs, no inheritance. Structs have value semantics. A variable with a type of some interface implies it's a pointer, with reference semantics and a VMT.


December 29
On Friday, December 29, 2017 12:18:57 Mike Franklin via Digitalmars-d-learn wrote:
> On Friday, 29 December 2017 at 12:11:46 UTC, rikki cattermole
>
> wrote:
> > Structs are structs, classes are classes.
>
> I'm talking about interfaces, which are neither structs nor classes.

Interfaces are related to classes and not structs. Structs do not have inheritance and do not implement interfaces in any way shape or form. Classes and interfaces are always references, whereas structs never are, and structs do not have virtual functions. Structs are either directly placed where they are (be it on the stack or inside an object that contains them), or they're placed on the heap and accessed via a pointer. As such, in D, structs are fundamentally different from classes or interfaces.

If you want a function to accept multiple types of structs or classes which share the same API, then use templates and use the template constraint to restrict what the template accepts. That's what's done with ranges (e.g. with isInputRange and isForwardRange).

- Jonathan M Davis

December 29
On Fri, 29 Dec 2017 12:39:25 +0000, Nicholas Wilson wrote:

> On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
>
> The problem is that interfaces are a runtime thing (e.g. you can cast a
> class to an interface)
> structs implement compile time interfaces via template duck typing
> (usually enforced via an if()).
> you could probably write a wrapper that introspected an interface and
> enforced that all members were implemented.

I've actually thought about doing this to get rid of a bunch of if qualifiers in my function declarations. `static interface {}` compiles but doesn't [currently] seem to mean anything to the compiler, but could be a hint to the programmer that nothing will directly implement it; it's a compile-time interface. This would provide a more generic way of doing stuff like `isInputRange`, etc.
December 29
On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> In C#, structs can inherit from and implement interfaces.
>
> ----
> using System;
>
> interface IPrint
> {
>     void Print();
> }
>
> struct MyStruct : IPrint
> {
>     public void Print()
>     {
>         Console.WriteLine(ToString());
>     }
> }
>
> public class Program
> {
>     public static void Main()
>     {
>         MyStruct s = new MyStruct();
>         s.Print();
>     }
> }
> ----
> https://dotnetfiddle.net/lpXR1O
>
> But in D it doesn't appear possible.
> ----
> import std.stdio;
>
> interface IPrint
> {
>     void print();
> }
>
> // Error: base classes are not allowed for struct, did you mean ;?
> struct MyStruct : IPrint   // Error: base classes are not allowed for struct, did you mean ;?
> {
>     void print()
>     {
>         writeln("MyStruct");
>     }
> }
>
> void main()
> {
> 	MyStruct s;
>     s.Print();
> }
> ----
> https://run.dlang.io/is/j4xwla
>
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?
>
> Thanks for your insight,
>
> Mike

This feature is criticized among the C# community:

https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/

no vtable means for example that you cannot back to something after extracting the interface (with classes you can always get back to Object)

as in D, struct should really only be used for a custom type with value semantic.
December 29
On 29/12/2017 12:59 PM, rjframe wrote:
> On Fri, 29 Dec 2017 12:39:25 +0000, Nicholas Wilson wrote:
> 
>> On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
>>
>> The problem is that interfaces are a runtime thing (e.g. you can cast a
>> class to an interface)
>> structs implement compile time interfaces via template duck typing
>> (usually enforced via an if()).
>> you could probably write a wrapper that introspected an interface and
>> enforced that all members were implemented.
> 
> I've actually thought about doing this to get rid of a bunch of if
> qualifiers in my function declarations. `static interface {}` compiles but
> doesn't [currently] seem to mean anything to the compiler, but could be a
> hint to the programmer that nothing will directly implement it; it's a
> compile-time interface. This would provide a more generic way of doing
> stuff like `isInputRange`, etc.

Or we could get signatures, which are even better still!

« First   ‹ Prev
1 2